我被分配了清理类层次结构的任务,但我有点墨守成规。我现在剩下的东西大致如下所示:
class Base
{
Base() = 0;
function1();
...
function5();
protected:
int variable1_;
...
int variable10_;
};
class DerivedOne
: public Base
{
DerivedOne() = 0;
function6();
...
function10();
protected:
int variable11_;
...
int variable20_;
};
class DerivedTwo
: public DerivedOne
{
DerivedTwo()
: DerivedOne()
{
... Fill variable1_ to variable25_ with data read from file ...
variable1_ = ...
}
function11();
...
function15();
private:
int variable21_;
...
int variable25_;
};
所以25个变量在DerivedTwo中赋值,很容易出错。当另一个类继承自 DerivedOne 时,几乎可以肯定那个人会忘记初始化其中一个变量。
我一直在尝试不同的方式来设计这个层次结构,但感觉没有什么是对的。
我知道在不知道这些类实际做什么的情况下很难说出具体的事情,但我很想知道这种设计是否存在根本性错误,或者我是否忽略了一些初始化所有变量的优雅方法。
最佳答案
派生的原则是先构造基础对象,后派生。这需要 Base 和 DerivedOne 构造函数自行生成有效对象。
在构造 DerivedTwo 时,您的代码明确说明了这一点:
DerivedTwo()
: DerivedOne() // First the base object constructor is called, before anything else
{
// then remaining initialisation, after DerivedOne() was created
}
因此每个类至少应该将自己的变量初始化为一个初始有效状态,使其自己的函数能够以一致的方式处理。
Base() : variable1_(/*default value here*/), variable10_(/*default value here*/) {}
Base(int v1, int v10) : variable1_(v1), variable10_(v10) {} // for convenience
派生类之后可以覆盖其基类的变量。使用getters/setters当然会更安全更优雅,但没关系。
如果采用这种设计,如果一个子派生类忘记初始化其父类之一的变量,这不应该导致灾难,因为至少基对象是以一种体面的方式初始化的。
现在的问题是您还通过读取文件来启动 DerivedTwo。请记住,首先创建 Base,然后创建 DerivedOne,然后只有 DerivedTwo 读取值。当文件无法读取或不一致时会发生什么?除非抛出异常,否则您最终可能会得到一个不一致的对象。所以你必须管理它并确保 DerivedTwo 处于稳定状态:
DerivedTwo()
: DerivedOne() // First the base object constructor is called
{
// then initialise all own members to a consitent state
// then try to read the file and manage potential errors
}
关于c++ - 在类层次结构中初始化变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24786513/