Помогите с этими предупреждениями. [наследование]

У меня есть набор кода, который имитирует базовую систему каталогизации библиотеки. Существует базовый класс с именем items, в котором определены общие переменные id, title и year, а также 3 других производных класса (DVD, Book и CD).

База [Предметы]

Получено [DVD, Книга, CD].

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

>"C:\Program Files\gcc\bin/g++"  -Os -mconsole -g -Wall -Wshadow -fno-common mainA4.cpp -o mainA4.exe
In file included from mainA4.cpp:5:
a4.h: In constructor `DVD::DVD(int, std::string, int, std::string)':
a4.h:28: warning: `DVD::director' will be initialized after
a4.h:32: warning:   base `Items'
a4.h:32: warning:   when initialized here
a4.h: In constructor `Book::Book(int, std::string, int, std::string, int)':
a4.h:48: warning: `Book::numPages' will be initialized after
a4.h:52: warning:   base `Items'
a4.h:52: warning:   when initialized here
a4.h: In constructor `CD::CD(int, std::string, int, std::string, int)':
a4.h:66: warning: `CD::numSongs' will be initialized after
a4.h:70: warning:   base `Items'
a4.h:70: warning:   when initialized here
>Exit code: 0

person silent    schedule 02.05.2010    source источник


Ответы (3)


Когда вы объявляете переменные-члены в классе, они инициализируются в том порядке, в котором вы их объявляете. Но вы можете писать их в любом порядке в списке инициализаторов вашего конструктора. Например,

struct foo {
   int a;
   int b;

   foo(): b(5), a(3) {}
};

создаст a и затем b, даже если кажется, что вы инициализируете их в другом порядке.

Компилятор выдает предупреждение, потому что вы можете обманом написать неправильный код. Например,

struct foo {
    int a;
    int b;

    foo(): b(5), a(b) {}
};

значение a будет неопределенным.

person Jesse Beder    schedule 02.05.2010

Вам нужно взглянуть на свои конструкторы и списки инициализации членов. Трудно сказать, не видя кода, но происходит то, что у вас есть такой код: -

class my_class : public base1, public base2
{
    public:
        my_class();

    private:
        member1 member1_;
        member2 member2_;
}

my_class::my_class() 
    : member2_(...)
    , member1_(...)
    , base2_(...)
    , base1_(...)
{ }

Это приведет к появлению аналогичных предупреждений. Причина в том, что в C ++ конструктор всегда создает базовые классы в порядке, указанном в списке базовых классов (base1, за которым следует base2), а затем конструирует переменные-члены сверху вниз в определении класса. Он делает это безотносительно к порядку, который вы указываете в своем списке инициализации участников - этот порядок игнорируется, но если он не соответствует, некоторые компиляторы (включая ваш, похоже) предупредят вас об этом.

Причина, по которой он делает это, между прочим, заключается в том, что C ++ имеет строгое требование, чтобы деструкторы вызывались в обратном порядке конструкторов, поэтому, если бы он выполнял действия в порядке списков инициализации членов, он должен был бы каким-то образом «запомнить», какой конструктор имел был вызван, чтобы он мог вызывать деструкторы в правильном порядке. Он этого не делает, а просто всегда использует один и тот же порядок.

person Stewart    schedule 02.05.2010

Когда вы инициализируете члены класса в конструкторе, инициализируйте их в том же порядке, в котором они объявлены. Например.:

class Foo {
  public:
    int a;
    int b;
    Foo() : a(0), b(0) {}
};

В конструкторе Foo() изменение порядка a и b приведет к появлению предупреждений. То же самое касается инициализации базовых классов (конструкторы которых, если они вызываются явно, должны вызываться перед инициализаторами любых элементов данных).

person DS.    schedule 02.05.2010