Список инициализации C ++ игнорирует вызов конструктора родительского класса

0

В следующем коде построение класса C начинается с инициализации A, затем B1, а затем B2 и, наконец, класса C. Однако при инициализации B1 и B2 отладчик проигнорировал инициализацию A (1) и A (2) (которые появляются в списке инициализации B1 и B2 в этом порядке), но не игнорировали инициализацию B2 (3) в списке инициализации C.

Почему это?

Заранее спасибо.

Вот код:

struct A { 
    int i; 
    A() { i = 0; } 
    A(int _i) : i(_i) {} 
    virtual void f() { cout << i; } 
}; 

struct B1 : virtual A { 
    B1() : A(1) { f(); } 
    void f() { cout << i+10; } 
}; 

struct B2 : virtual A { 
    B2(int i) : A(2) { f(); } 
}; 

struct C : B1, B2 { 
    C() : B2(3) {} 
};

int _tmain(int argc, _TCHAR* argv[])
{
    C* c = new C();
    return 0;
}
Теги:
inheritance
initialization-list

2 ответа

0
Лучший ответ

Именно так компилятор избегает "алмаза смерти". Если бы были вызваны A (1) и A (2), значит, была дублирующая инициализация базового класса, это цель виртуального наследования - удалить неоднозначные общие базовые элементы.

2

Для virtual баз наиболее производный класс должен предоставить аргументы конструктора, например:

struct C
    : B1, B2 { 
    C()
        : A(17)
        , B2(3) {} 
};

Если самый производный класс не упоминает virtual базу в своем списке инициализаторов, используется конструктор по умолчанию virtual базы (если их нет, это ошибка).

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню