将派生类的构造方法声明为父类的朋友

问题描述 投票:0回答:1

作为每个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_,但nrows_和ncols_仍大于1。这样,我仍然可以使用为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类采取不同的方法?

欢呼声

c++ inheritance constructor
1个回答
4
投票

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

您还可以在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而不是两个数字,但是还有其他方法可以避免歧义。

© www.soinside.com 2019 - 2024. All rights reserved.