迄今为止,还不错,但是有一个棘手的问题我们还没有提及。SquareMatrixBase::invert 怎样知道应操作什么数据?它从它的参数知道矩阵的大小,但是它怎样知道一个特定矩阵的数据在哪里呢?大概只有 derived class(派生类)才知道这些。derived class(派生类)如何把这些传达给 base class(基类)以便于 base class(基类)能够做这个转置呢?
一种可能是为 SquareMatrixBase::invert 增加另一个的参数,也许是一个指向存储矩阵数据的内存块的开始位置的指针。这样可以工作,但是十有八九,invert 不是 SquareMatrix 中仅有的能被写成一种 size-independent(大小无关)的方式并移入 SquareMatrixBase 的函数。如果有几个这样的函数,全都需要一种找到持有矩阵内的值的内存的方法。我们可以为它们全都增加一个额外的参数,但是我们一再重复地告诉 SquareMatrixBase 同样的信息。这看上去不太正常。
一个可替换方案是让 SquareMatrixBase 存储一个指向矩阵的值的内存区域的指针。而且一旦它存储了这个指针,它同样也可以存储矩阵大小。最后得到的设计大致就像这样:
template class SquareMatrixBase { protected: SquareMatrixBase(std::size_t n, T *pMem) // store matrix size and a : size(n), pData(pMem) {} // ptr to matrix values
void setDataPtr(T *ptr) { pData = ptr; } // reassign pData ...
private: std::size_t size; // size of matrix T *pData; // pointer to matrix values }; |
这样就是让 derived classes(派生类)决定如何分配内存。某些实现可能决定直接在 SquareMatrix object 内部存储矩阵数据:
template class SquareMatrix: private SquareMatrixBase { public: SquareMatrix() // send matrix size and : SquareMatrixBase(n, data) {} // data ptr to base class ...
private: T data[n*n]; }; |
这种类型的 objects 不需要 dynamic memory allocation(动态内存分配),但是这些 objects 本身可能会非常大。一个可选方案是将每一个矩阵的数据放到 heap(堆)上:
template class SquareMatrix: private SquareMatrixBase { public: SquareMatrix() // set base class data ptr to null, : SquareMatrixBase(n, 0), // allocate memory for matrix pData(new T[n*n]) // values, save a ptr to the { this->setDataPtr(pData.get()); } // memory, and give a copy of it ... // to the base class
private: boost::scoped_array pData; // see Item 13 for info on }; // boost::scoped_array |
<<上一页
1
2
3
4
下一页>>
|