我目前的情况如下。这或多或少是一个简单的继承案例,我对此有很多问题
我有一个抽象类(=它有纯虚拟函数(,有两个变量foo_
和bar_
。CCD_ 3由构造函数中的一个参数设置。对于大多数子类,bar_
应该默认为1000,但我希望有一个特定的类将其覆盖为50000。
下面是一个代码片段:
class Base {
protected:
const int foo_;
const int bar_;
public:
Base(int foo) : foo_{foo}, bar_{1000} {}
}
class Derived : public Base {}
首先,有一个快速的问题:是像我在示例中那样在初始化列表中初始化bar_
更好,还是在变量声明为const int bar_{1000};
的顶部进行?
第二个快速问题:在初始化列表中使用{}
可以吗?还是应该使用()
?
如何正确编写派生类的构造函数?我想专门调用我为Base定义的构造函数,并使用初始化列表将bar_
设置为50000。
我的想法是这样的:
Derived(int foo) : Base(foo), bar_{50000} {}
编辑:经过一番尝试,我注意到修改Derived的构造函数列表中的bar_显然是不可能的,因为"bar_" is not a nonstatic data member or base class of class "Derived"
。
是像我在示例中那样在初始化列表中初始化bar_更好的做法,还是在变量声明为const int bar_{1000}的顶部进行;?
这与其说是"最佳实践",不如说是"你想要什么"?1000
是默认的初始值,它被构造函数中的初始值设定项"覆盖"。你可以有默认的初始化器,例如一个构造函数使用不同的初始化器和一个不使用的构造函数。
如何正确编写派生类的构造函数?
您可以编写一个受保护的构造函数,允许您传递两个值:
class Base {
protected:
const int foo_;
const int bar_;
Base(int foo, int bar) : foo_(foo), bar_(bar) {}
public:
Base(int foo) : foo_{foo}, bar_{1000} {}
};
class Derived : public Base {
public:
Derived(int foo) : Base(foo,5000) {}
};
这个问题有很多方面需要解决。
我对初始化的偏好是:
class Base {
protected:
const int foo_{};
const int bar_{1000};
public:
Base(int foo) : foo_{foo} {}
}
我喜欢这样做的原因是因为一个类可以有多个构造函数。这样可以更容易地维护默认值。
对于初始化的问题,我放弃了。只需使用现有的样式指南。(目前,他们似乎在所有地方使用{}都是标准化的(除了构造函数之外,初始化更麻烦,如果你想对细节感到震惊,我可以推荐:Nicolai Josuttis"C++初始化的噩梦"。
对于在派生类中编写构造函数,我认为您的成员不应该受到保护。如果它是私有的,那么写它的唯一方法是:
class Base {
private:
const int foo_{};
const int bar_{1'000};
protected:
Base(int foo, int bar) : foo_{foo}, bar_{bar} {}
public:
Base(int foo) : foo_{foo} {}
}
class Derived : public Base {
public:
Derived(int foo) : Base{foo, 50'000} {}
}
这样,我就可以通过一个受保护的方法公开对它们的访问。即使忽略了这个建议,我也会使用这种技术来初始化它,因为如果只看"Base"类,最容易理解会发生什么。