c++ - 在类层次结构中初始化变量

标签 c++ class oop inheritance design-patterns

我被分配了清理类层次结构的任务,但我有点墨守成规。我现在剩下的东西大致如下所示:

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/

相关文章:

java编程和静态类

PHP/Laravel - 无法启动抽象类的扩展

C++ Unicode 问题

c++ - std future 异常 - 已检索,std bug?

c++ - 在另一个构造函数中调用对象数组的构造函数

ios - Swift 3 - 将 bool 值发送到不同的类

c++ - 虚函数重载

java - 类属性声明,属性属性的顺序(最终、私有(private)、静态、类型)

c# - 创建一个包罗万象的 AppToolbox 类——这是一种不好的做法吗?

java - 在数组列表中的各种对象上调用子方法