C++:如何强制派生类设置基成员变量?

mba*_*i23 5 c++ inheritance

我有一个带有成员变量的基类(最好是private),并且我需要强制派生类使用基于其实现的值来初始化它;很像纯虚函数。

为了澄清,我想在 Base 中声明一个成员,让派生类对其进行初始化,如果不这样做,则会出现编译器错误。在下面的代码中,我将默认构造函数声明Baseprotected。然后声明默认构造函数Derivedprivate

class Base {
private:
    int _size;

protected:
    Base(){}
    /* pure virtual methods */

public:
    Base(int size) : _size(size){} // must enforce derived to call this.
    virtual ~Base(){}

    /* more pure virtual methods */
};

class Derived : public Base {
private:
    Derived() {}
public:
    Derived(int size) : Base(size) {
        //Base::Base(size);
    }
};

int main()
{
    Derived* d1 = new Derived();    // throws an error as needed: 
                                    // "Cannot access private member declared in class 'Derived'"

    Derived* d2 = new Derived;      // throws an error as needed: 
                                    // "Cannot access private member declared in class 'Derived'"

    Derived* d3 = new Derived(5);   // works as needed

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面代码的问题是,如果 的另一个定义Derived没有隐藏默认构造函数。我仍然坚持未初始化的Base::_size.

我不知道除了继承之外是否还有其他方法可以解决这个问题,因为我仍然需要派生类来为Base.

任何指示表示赞赏。

dyp*_*dyp 3

在对调用基类 ctor 和默认 ctor 感到困惑之后,也许解决方案就是不包含默认 ctor Base

class Base {
private:
    int _size;

public:
    // no default ctor
    Base(int size) : _size(size) {} // must enforce derived to call this.
    virtual ~Base(){}

    /* more pure virtual methods */
};

class Derived : public Base {
public:
    // no default ctor
    Derived(int size) : Base(size){
    }
    // examplary default ctor:
    //Derived() : Base(42) {}
};

int main()
{
    Derived d1;                   // error: no default ctor
    Derived* d2 = new Derived;    // same, but why use the free store?

    Derived d3(5);                // works as needed
    Derived* d4 = new Derived(5); // same, but why use the free store?

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为了明确没有默认构造函数,可以使用

class Base {
    /* ... */
    Base() = delete;
    /* ... */
};
Run Code Online (Sandbox Code Playgroud)