C++ C++;:如何强制派生类来设置基成员变量?
我有一个带有成员变量的基类(最好是C++ C++;:如何强制派生类来设置基成员变量?,c++,inheritance,C++,Inheritance,我有一个带有成员变量的基类(最好是private),我需要强制派生类根据它们的实现用一个值初始化它;很像一个纯虚函数 为了澄清这一点,我想在Base中声明一个成员,让派生类初始化它,如果它们没有初始化,就会得到一个编译器错误。在下面的代码中,我将Base的默认构造函数声明为protected。然后将派生的的默认构造函数声明为私有 类基{ 私人: 内部尺寸; 受保护的: Base(){} /*纯虚拟方法*/ 公众: Base(int size):\u size(size){}//必须强制派生才能调
private
),我需要强制派生类根据它们的实现用一个值初始化它;很像一个纯虚函数
为了澄清这一点,我想在Base中声明一个成员,让派生类初始化它,如果它们没有初始化,就会得到一个编译器错误。在下面的代码中,我将Base
的默认构造函数声明为protected
。然后将派生的
的默认构造函数声明为私有
类基{
私人:
内部尺寸;
受保护的:
Base(){}
/*纯虚拟方法*/
公众:
Base(int size):\u size(size){}//必须强制派生才能调用此函数。
虚拟~Base(){}
/*更纯粹的虚拟方法*/
};
派生类:公共基{
私人:
派生(){}
公众:
派生(整数大小):基(大小){
//Base::Base(大小);
}
};
int main()
{
派生的*d1=new-Derived();//根据需要抛出错误:
//“无法访问在类“派生”中声明的私有成员”
派生的*d2=新派生的;//根据需要引发错误:
//“无法访问在类“派生”中声明的私有成员”
派生的*d3=新派生的(5);//根据需要工作
返回0;
}
上述代码的问题在于,如果派生的的另一个定义没有隐藏默认构造函数。我仍然坚持使用未初始化的基::\u size
我不知道除了继承之外是否还有其他方法,因为对于Base
中声明的几个方法,我仍然需要派生类来实现它们自己的行为
欢迎使用任何指针。使用构造函数
基类1{
受保护的:
Base1(整数向前){
thingYouWantToHide=前进;
}
私人:
你想隐藏的东西;
};
您可能认为Derived2可以工作,但请记住,在构建Base2之前,Derived2不会被构造,因此在构建Base2时,virtual是一个未定义的引用
如果类型是常量(静态常量)或基本类型,则应使用第一种情况类型traits。在混淆了如何调用基类构造函数和默认构造函数之后,也许解决方案就是在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;
}
为了明确说明没有默认的构造函数,可以使用
class Base {
/* ... */
Base() = delete;
/* ... */
};
Base::Base(大小)代码>这可能不是您认为它所做的。如果要调用基类ctor,请使用mem初始值设定项列表:Derived(int size):base(size){/*…*/}
Yes,谢谢。刚刚编辑了代码。使用带参数的构造函数将自动删除默认构造函数。您不需要创建一个私有的。@NeilKirk是的,但它不强制用户使用参数化的ctor。如果类未显式定义默认构造函数,则编译器会自动创建该构造函数。对吗?@mbadawi23如果有用户声明的ctor,则默认ctor不会被隐式声明。我不确定我是否正确理解您的意思,使用您的Base2
和Derived2
我会收到未解析的Base2::calledToGet()
的链接器错误。当然,因为编译器希望Base2
完整。你能详细说明一下你提出的解决方案吗。
class Base {
/* ... */
Base() = delete;
/* ... */
};