2011-02-10 83 views
0

比方说,我有一个基类模板MyBase:子类有不同的阵列实现

template <class T> 
class MyBase{ 
private: 
    T data; 
public: 
    MyBase(T _data); 
}; 

我想(至少目前如此)两次此类子:

  1. 数据应该是一个动态的2维数组:T **data
  2. 数据应该是一个固定的2维数组:T data[rows][cols]

我仍然是一个C++新手,我不知道如何做到这一点。 具体来说,我想制作一种矩阵库(主要是作为一个学习项目)。过去我做过一些事情,我的矩阵动态存储更有意义,反之亦然。所以,看起来好的解决方案是实现一个提供所有常用功能的基类(例如insert(T item, int i, int j),无论在哪种情况下都应该使用data[i][j] = item;),然后继承DynamicMatrix和FixedMatrix。该DynamicMatrix将有一个构造函数,没有

data = new T*[rows]; 
for (int i = 0; i < rows; i++) 
{ 
    data[i] = new T[cols]; 
} 
for (int i = 0; i < rows; i++) 
{ 
    for (int j = 0; j < cols; j++) 
    { 
     data[i][j] = 0; 
    } 
} 

而且FixedMatrix刚:

for (i=0; i < rows; i++) 
{ 
    for (j=0; j < cols; j++) 
    { 
     data[i][j] = 0;  
    } 
} 

在基类中创建一个成员变量T data;是很容易的。但是,在子类中,我该如何将它转换为双指针?也许我做不到,我没关系。但是,我应该怎么做呢?

+2

你能详细解释一下这个基类代表什么,你为什么要在这里使用继承,以及你有什么麻烦? – templatetypedef 2011-02-10 05:43:43

+0

当然,让我编辑这个问题。 – jakev 2011-02-10 05:44:49

回答

3

在这里,您尝试使用继承进行代码重用,在我看来,这不是一种好的设计方法;继承是为了实现自由,而构成是为了代码重用。

在这种情况下,如果它是真的有必要支持这些不同的情况,我就正式的二维数组:

template<typename T> class Array2D { 
    public: 
     virtual const T* operator[](int row_index) const = 0; 
     virtual T* operator[](int row_index) = 0; 
     virtual size_t rows() const = 0; 
     virtual size_t cols() const = 0; 
}; 

然后,我将提供Array2D的实现,您指定:

template<typename T, int R, int C> class FixedArray2D : public Array2D { 
    public: 
     virtual const T* operator[](int row_index) const { 
      return &data_[row_index][0]; 
     } 
     virtual T* operator[](int row_index) { 
      return &data_[row_index][0]; 
     } 
     virtual size_t rows() const { return R; } 
     virtual size_t cols() const { return C; } 
    private: 
     T data_[R][C]; 
}; 

template<typename T> class DynamicArray2D : public Array2D { 
    public: 
     DynamicAray2D(int rows, int cols) { 
      // ... 
     } 
     // ... 
}; 

此时,您可以使用任一格式实例化Array2D。现在无论你使用什么代码,只要需要处理这样一个对象,只需要一个const Array2D&Array2D&。这就是说,我认为这可能是不必要的复杂性,因为动态大小的数组可能适用于任何一种情况,因此除非有令人信服的理由支持这两种类型,否则我只会继续这样做。