5

我有一个带有成员变量的基类(最好是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;
}

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

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

任何指针表示赞赏。

4

2 回答 2

3

在对调用基类 ctor 和默认 ctor 感到困惑之后,也许解决方案只是没有默认 ctor in 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;
}

要明确表示没有默认 ctor,可以使用

class Base {
    /* ... */
    Base() = delete;
    /* ... */
};
于 2013-10-09T00:30:26.297 回答
0

使用构造函数

类 Base1 { protected: Base1(int forward) { thingYouWantToHide = forward; } 私有的:int thingYouWantToHide;};

class Derived1: public Base1 {
public:
    Derived1(): Base1(5) {}
};

class Base2 {
private:
    int value;
protected:
    Base2() {
        value = calledToGet();
    }
    virtual int calledToGet() = 0;

    virtual ~Base2() {} //shut compiler warnings up
};

class Derived2: public Base2 {
    virtual int calledToGet() {
        return 5;
    }
};

int main(int,char**) {
    Derived1 a;
    Derived2 b;
    return 0;
}

您可能认为 Derived2 会起作用,但请记住,Derived2 直到 Base2 才被构造,因此当 Base2 被构造时 virtual 是一个未定义的引用。

如果它是常量(静态常量)或类型的基础,则应使用第一种情况,即类型特征。

于 2013-10-08T23:15:47.227 回答