Виртуальное наследование: базовый Ctor не вызывается в самом производном классе? - PullRequest
3 голосов
/ 10 марта 2010
class Base
{
      public:
          Base(){}
          Base(int k):a(k) 
          {     
          }
            int a;
};

class X:virtual public Base
{
      public:
            X():Base(10){}
            int x;
};

class Y:virtual public Base
{
      public:
            Y():Base(10){}
            int y;
};

class Z:public X,public Y
{
public:
    Z():X(10){}
};

int main()
{
           Z a;
           cout << a.a;
           return 1;
}

В вышеприведенном случае для Z():X(10){} Base(int k):a(k) не вызывается, но когда я переключаюсь на Z():Base(10){}, вызывается Base(int k):a(k). Почему?

Спасибо.

Ответы [ 3 ]

7 голосов
/ 10 марта 2010

Поскольку вы использовали ключевое слово virtual - это именно то, что оно делает.

Вы должны явно инициализировать Base в списке инициализаторов Z, чтобы устранить неоднозначность между инициализацией в X и инициализация в Y.

3 голосов
/ 10 марта 2010

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

0 голосов
/ 10 марта 2010

Список инициализаторов в самом производном конструкторе используется для инициализации ваших базовых классов. Поскольку класс Z наследуется от классов X и Y, которые наследуются от общего базового класса, ключевое слово virtual используется для создания только одного подобъекта для базового класса, чтобы устранить неоднозначность при доступе к члену данных a.

...