菱形多重继承模式

时间:2012-02-16 09:17:43

标签: c++ polymorphism multiple-inheritance diamond-problem

以下是多重继承中遇到的钻石问题,

class Base {
 public:
  Base() {
    cout << "Empty Base constructor " << endl; 
  }
  Base(const string & strVar) { 
    m_strVar = strVar; 
    cout << m_strVar << endl;
  }
  virtual ~Base() {
    cout << "Empty Base destructor " << endl;
  }
  virtual const string & strVar() const { 
   return m_strVar; 
  }

  string m_strVar;
};

class Derived1: public virtual Base {
 public:
  Derived1() {
    cout << "Empty Derived1 constructor " << endl; 
  }
  Derived1(const string & strVar) : Base(strVar) {
    cout << " Derived1 one arg constructor" << endl;
  }
  ~Derived1() {
    cout << "Empty Derived1 destructor " << endl;
  }
};

class Derived2: public virtual Base {
 public:
  Derived2() {
    cout << "Empty Derived2 constructor " << endl; 
  }
  Derived2(const string & strVar) : Base(strVar) {
    cout << "Derived2 one arg constructor" << endl;
  }
  ~Derived2() {
    cout << "Empty Derived2 destructor " << endl;
  }
};

class Derived: public Derived1, public Derived2 {
 public:
  Derived(const string & strVar) : Derived1(strVar), Derived2(strVar) {
    cout << "Derived Constructor " << endl; 
  }
  ~Derived() {
    cout << "Empty Derived destructor " << endl;
  }
};

int main() {
  Derived derObj ("Print this if you can ! "); 
}

我得到的输出是

  1. 空基础构造函数
  2. Derived2 one arg constructor
  3. Derived1 one arg constructor
  4. 派生构造函数
  5. Empty Derived destructor
  6. 清空Derived2析构函数
  7. 清空Derived1析构函数
  8. 空基础析构函数
  9. 我想知道为什么我的derObj参数,即“如果可以的话打印”不打印,输出不像

    1. 空基础构造函数
    2. Derived2 one arg constructor
    3. 如果可以,请打印此内容!
    4. Derived1 one arg constructor
    5. 派生构造函数
    6. Empty Derived destructor
    7. 清空Derived2析构函数
    8. 清空Derived1析构函数
    9. 空基础析构函数

1 个答案:

答案 0 :(得分:6)

这与虚拟继承有关。

当一个类被虚拟继承时,层次结构中大多数派生类的责任就是调用它的构造函数:here Derived

由于Base是默认可构造的,并且您没有精确的任何内容,Derived会调用Base的默认构造函数。

如果要打印字符串,请使用:

Derived(const string & strVar) : Base(strVar), Derived1(strVar), Derived2(strVar)
{
  std::cout << "Derived Constructor\n"; 
}

您可以删除默认构造函数以让编译器诊断问题,但并非所有编译器都提供非常有用的消息。