GCC 4.5.1 проблема виртуального наследования - PullRequest
6 голосов
/ 09 февраля 2012

Давайте начнем с фрагмента кода:

#include <iostream>

struct God{
    God(){_test = 8;}
    virtual ~God(){}
    int _test;
};

struct Base1 : public virtual God{
    //Base1(){std::cout << "Base1::Base1" << std::endl;}  //enable this line to fix problem
    virtual ~Base1(){}
};

struct Base2 : public virtual Base1{
    virtual ~Base2(){}
};

struct A1 : public virtual Base2{
    A1(){std::cout << "A1:A1()" << std::endl;}
    virtual ~A1(){};
};

struct A2 : public virtual Base2{
    A2(){std::cout << "A2:A2()" << std::endl;}
    virtual ~A2(){};
};


struct Derived: public virtual A1, public virtual A2{
    Derived():Base1(){std::cout << "Derived::Derived()" << std::endl;}
    Derived(int i){std::cout << "Derived(i)::Derived(i)" << std::endl;}         
    virtual ~Derived(){}
};


int main(){

    God* b1 = new Derived();
    std::cout << b1->_test << std::endl;    //why it prints 0?

    God* b2 = new Derived(5);
    std::cout << b2->_test << std::endl;

    return 0;
}

Скомпилировано с GCC 4.5.1 и 4.6.1. Единственное различие между конструкторами класса Derived заключается в том, что первый явно указывает, какой конструктор Base1 следует вызвать.Я ожидаю, что оба метода cout в main () напечатают 8. К сожалению, первый выводит 0 !.

Почему?

Если я включу явное определение конструктора Base1, это решит проблему.Если я удалю виртуальное наследование в определении производного класса (класс Derived: общедоступный A1, общедоступный A2), это также сработает.Это ожидаемое поведение?

Эта проблема не наблюдается в GCC 3.4.4 или компиляторе Microsoft (VS)

Ответы [ 2 ]

1 голос
/ 09 февраля 2012

Я тестировал с несколькими более старыми версиями (до 4.3 - что работает) - нет под рукой серии 4.4 (буду тестировать утром), но я согласен, это похоже на ошибку (а не вд.б.) наверное стоит его поднять.

Однако я заметил, что если вы измените первое отношение (Base1 на God с виртуального на не виртуальный), то этот пример будет работать как ожидалось.Я полагаю, это зависит от ваших потребностей, будете ли вы напрямую вызывать ctor God из самого производного класса (хотя я никогда раньше не видел этот подход ...)

1 голос
/ 09 февраля 2012

Это должна быть ошибка компилятора.Я также проверил GCC 4.2.1, и результат составил 8 в обоих случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...