ромбовидная форма множественного наследования - PullRequest
2 голосов
/ 16 февраля 2012

Ниже приведена проблема с алмазом при множественном наследовании,

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 конструктор с одним аргументом
  3. Производный одно конструктор arg
  4. Производный конструктор
  5. Пустой производный деструктор
  6. Пустой деструктор Derived2
  7. Пустой деструктор Derived1
  8. Пустой базовый деструктор

Интересно, почему мой параметр derObj, т. Е. «Распечатай это, если сможешь», не печатается, а вывод не похож на

  1. Пустой базовый конструктор
  2. Derived2 конструктор с одним аргументом
  3. Распечатайте это, если можете!
  4. Derived1 конструктор с одним аргументом
  5. Производный конструктор
  6. Пустой производный деструктор
  7. Пустой деструктор Derived2
  8. Пустой деструктор Derived1
  9. Пустой базовый деструктор

1 Ответ

6 голосов
/ 16 февраля 2012

Это связано с виртуальным наследованием.

Когда класс наследуется виртуально, это самый ответственный класс в иерархии, который вызывает его конструктор: здесь Derived.

Поскольку Base является конструируемым по умолчанию, и вы ничего не указали, Derived вызывает конструктор по умолчанию Base.

Если вы хотите, чтобы строка была напечатана, используйте:

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

Вы можете удалить конструктор по умолчанию, чтобы позволить компилятору диагностировать проблему, хотя не все компиляторы выдают очень полезные сообщения.

...