我可以避免 Matrix 类迭代器中的循环依赖吗?

发布于 2024-09-02 07:05:58 字数 401 浏览 6 评论 0原文

我们有两个类:

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix

Matrix

template<typename T, typename Size>
class Iterator

应该能够返回开始和结束迭代器,并且 Iterator 将保留对 Matrix 的引用以通过其接口访问元素。我们不希望Iterator依赖于Matrix的内部存储来防止耦合。我们如何解决这个循环依赖问题呢?

(内部Storage类具有与Matrix类相同的模板参数以及与Matrix本身相同的访问过程)

We have two classes:

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix

and

template<typename T, typename Size>
class Iterator

Matrix should be able to return begin and end iterators and Iterator will keep a referrence to the Matrix to access the elements via it's interface. We don't want Iterator to depend on the internal storage of the Matrix to prevent coupling. How can we solve this cyclic dependency problem?

(The internal Storage class has the same template parameters as the Matrix class and the same access procedures as the Matrix itself)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北恋 2024-09-09 07:05:58

首先,向前声明 Matrix 类。这允许 Iterator 类查看 Matrix 类的名称,并对其进行指针和引用。 (它还不允许 Iterator 类访问成员数据或调用成员函数。)

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix;

然后,定义 Iterator 类。此时它所能做的就是保存指向 Matrix 的引用和指针。 (还不能访问 Matrix 的成员。)

template<typename T, typename Size>
class Iterator{
   // don't define any function bodies in here
   //but do put all data members and prototypes in here
};

然后定义 Matrix 类(可以访问 Iterator 成员),

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix{
   // don't define any function bodies in here
   //but do put all data members and prototypes in here
};

然后定义每个类的方法体。此时,两个类的方法就可以访问彼此的成员了。通常,这部分位于 .cpp 文件中,但对于模板,它属于 .h 文件中。

template<typename T, typename Size, typename Stack, typename Sparse>
Matrix<T,Size,Stack,Sparse>::Matrix(){ /*...*/}

template<typename T, typename Size>
Iterator<T,Size>::Iterator(){ /*...*/ }

First, forward declare the Matrix class. This allows the Iterator class to see the name of the Matrix class, and make pointers and references to it. (It doesn't allow the Iterator class to access member data yet or call member functions yet.)

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix;

Then, define the Iterator class. All it can do at this point is hold references and pointers to the Matrix. (No access to Matrix's members yet.)

template<typename T, typename Size>
class Iterator{
   // don't define any function bodies in here
   //but do put all data members and prototypes in here
};

Then define the Matrix class (which can access Iterator members)

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix{
   // don't define any function bodies in here
   //but do put all data members and prototypes in here
};

Then define the method bodies for each class. At this point, the methods of both classes can access each other's members. Usually, this part goes in the .cpp file, but for templates it belongs in the .h file.

template<typename T, typename Size, typename Stack, typename Sparse>
Matrix<T,Size,Stack,Sparse>::Matrix(){ /*...*/}

template<typename T, typename Size>
Iterator<T,Size>::Iterator(){ /*...*/ }
饮惑 2024-09-09 07:05:58

在这里使用嵌套类也可能是合适的,并且它可能会减少您需要的模板参数的数量。

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix{
public:
   class Iterator{
       // define Iterator members here
   };
   // declare Matrix members here
}

Using a nested class might also be appropriate here, and it may cut down on the number of template parameters you need.

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix{
public:
   class Iterator{
       // define Iterator members here
   };
   // declare Matrix members here
}
停滞 2024-09-09 07:05:58

为了进行迭代,迭代器通常需要了解它们迭代的内部存储——这种耦合通常是无法避免的。以地图迭代器为例 - 它必须了解地图的内部树结构才能完成其工作。

In order to iterate, iterators typically do need to know about the internal storage they iterate over - this coupling can usually not be avoided. Take a map iterator for example - it is going to have to know about the internal tree structure of the map in order for it to do its job.

山色无中 2024-09-09 07:05:58

您可以前向声明模板。它看起来像这样:

template<typename T> struct Foo;

template <typename T> struct Bar
{
    Foo<T>* foo;
};

template<typename T> struct Foo
{
        T value;
        Bar<T*> foobar;
};

void bla()
{
        Foo<int> grml;
}

You can forward-declare a template. It looks like this:

template<typename T> struct Foo;

template <typename T> struct Bar
{
    Foo<T>* foo;
};

template<typename T> struct Foo
{
        T value;
        Bar<T*> foobar;
};

void bla()
{
        Foo<int> grml;
}
星星的軌跡 2024-09-09 07:05:58

在定义 Iterator 模板之前前向声明 Matrix 模板。

请注意,当您意识到 Iterator 无法引用 Matrix 时,您就会碰壁。 >。

Forward-declare the Matrix template before defining the Iterator template.

Mind you, you'll hit a brick wall when you realise that an Iterator<T, Size> can't refer to a Matrix<T, Size, Stack, Sparse>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文