我有一个带有成员变量的基类(最好是private
),我需要强制派生类用基于其实现的值初始化它;很像一个纯虚函数。
为了澄清,我想在Base中声明一个成员,派生类初始化它,如果不是,则会出现编译器错误。在以下代码中,我将Base
的默认构造函数声明为protected
。然后将Derived
的默认构造函数声明为private
。
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
中声明的几个方法实现自己的行为。
任何指针都表示赞赏。
答案 0 :(得分:2)
关于调用基类ctor和默认ctors的困惑之后,或许解决方案是在Base
中没有默认的ctor?
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;
/* ... */
};
答案 1 :(得分:0)
使用构造函数
类Base1 { 保护: 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是一个未定义的引用。
你应该使用第一种情况,类型特征,如果它是常量(静态常量)或类型的基础。