2

我们有两个班级:

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

template<typename T, typename Size>
class Iterator

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

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

4

5 回答 5

5

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

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

然后,定义 Iterator 类。此时它所能做的就是保存对矩阵的引用和指针。(还不能访问 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(){ /*...*/ }
于 2010-05-18T13:31:20.317 回答
4

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

template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix{
public:
   class Iterator{
       // define Iterator members here
   };
   // declare Matrix members here
}
于 2010-05-18T13:50:11.860 回答
2

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

于 2010-05-18T13:25:13.777 回答
1

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

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;
}
于 2010-05-18T13:23:59.987 回答
0

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

Iterator<T, Size>请注意,当您意识到 an不能引用 a时,您会碰壁Matrix<T, Size, Stack, Sparse>

于 2010-05-18T13:23:01.057 回答