将派生类的构造函数声明为父类的友元



和每个C++新手一样,我正在编写自己的矩阵类作为练习。我正在使用这样的类模板:

template<typename T>
class BMatrix {
public:
// Constructors
BMatrix(unsigned nrows, unsigned ncols);
BMatrix(unsigned nrows, unsigned ncols, T ival);
BMatrix(const BMatrix<T>& a);
// Destructor
~BMatrix();
// Access
T& operator() (unsigned row, unsigned col);
T  operator() (unsigned row, unsigned col) const;
// ...
// Friends
//friend BDiagonal<T>::BDiagonal(unsigned size, T val);
private:
unsigned nrows_, ncols_;
T* data_;
};

BMatrix 的构造函数分配一个大小为 nrows_*ncols_ 的数组data_。

现在,正如你所看到的,我想将另一个类的构造函数 BDiagonal 声明为朋友。类 BDiagonal 是 BMatrix 的派生类。这背后的动机是 BDiagonal 将节省内存(我只需要存储 nxn 对角矩阵的 n 个非零元素(并使一些操作更快。所以我希望这个矩阵的构造函数分配一个大小为 nrows*1 的数组data_,但仍有大于 1 的nrows_和ncols_。有了这个,我仍然可以使用我为 BMatrix 类实现的一些功能(例如用于打印矩阵的重载<<运算符(。

毫不奇怪,这没有编译,而是编译器抛出错误:

BArray/core.h:86:9: error: ‘BDiagonal’ does not name a type
friend BDiagonal<T>::BDiagonal(unsigned size, T val);

如果我在文件开头转发声明 BDiagonal,我会得到:

BArray/core.h:546:7: error: invalid use of incomplete type ‘class BMatrix<double>’
class BDiagonal : public BMatrix<T> {
^~~~~~~~~
BArray/core.h:55:7: note: declaration of ‘class BMatrix<double>’
class BMatrix {

我也尝试过前向声明 BMatrix,但这会导致更多错误。我不想声明 BMatrix 的私有成员受到保护,因为这会导致任何人都可以通过派生类直接访问它们。

有没有办法做到这一点?更重要的是,有什么理由让我不应该这样做,而在我的BDIagonal课程中采取不同的方法吗?

干杯

如果您需要在派生类中可访问某些内容,请使其受保护而不是私有。在这种情况下,您不需要朋友。

还可以在BMatrix中添加一个受保护的构造函数,该构造函数使用可在派生类构造函数中调用(委托(的所需数量的元素初始化data_

例如,您可以在下面添加受保护的构造函数

BMatrix(std::pair<unsigned, unsigned> dimension, unsigned int numElements);

然后在 BMatrix 中你会写

BMatrix(unsigned nrows, unsigned ncols) : BMatrix({nrows, ncols}, nrows * ncols) {}

BDiagonal可能的构造函数可能是

BDiagonal(size) : BMatrix({size, size}, size) {}

使用此BDiagonal只会为size元素分配空间,而不是size*size


编辑

我已经更改了受保护的构造函数以接收维度的std::pair而不是两个数字,以避免与接收T ival的构造函数产生歧义,但还有其他方法可以避免歧义。

最新更新