2010-05-02 13 views
5

Ho un set di codice, che riproduce un sistema di catalogazione delle librerie di base. Esiste una classe di base chiamata items, in cui sono definite le variabili di identificazione generale, titolo e anno e altre 3 classi derivate (DVD, Libro e CD).Aiuto con questi avvertimenti. [ereditarietà]

Base [Articoli]

Derivato [DVD, libri, CD].

I programmi vengono eseguiti, tuttavia ottengo i seguenti avvertimenti, non sono sicuro di come correggerli.

 
>"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 

risposta

28

Quando si dichiarano le variabili membro in una classe, vengono inizializzate nell'ordine in cui vengono dichiarate. Ma puoi scriverli in qualsiasi ordine nella lista di inizializzazione del tuo costruttore. Ad esempio,

struct foo { 
    int a; 
    int b; 

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

costruirà a e poib, anche se sembra che li stai inizializzazione in altro ordine.

Il compilatore emette un avviso perché è possibile ingannare se stessi scrivendo codice errato. Ad esempio,

struct foo { 
    int a; 
    int b; 

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

sarà indefinito il valore di a.

+0

La ringrazio molto – silent

+0

Grande risposta, grazie. –

3

Quando si inizializzano i membri della classe nel costruttore, inizializzarli nello stesso ordine in cui sono dichiarati. Es .:

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

In Foo() costruttore, passando l'ordine di a e b porterebbe ai tuoi avvertimenti. Lo stesso vale per l'inizializzazione delle classi di base (i cui costruttori, se chiamati esplicitamente, dovrebbero essere chiamati prima di qualsiasi inizializzatore di membri di dati).

6

È necessario dare un'occhiata ai costruttori e agli elenchi di inizializzazione dei membri. E 'difficile da dire senza vedere il codice, ma ciò che sta accadendo è che si dispone di codice in questo modo: -

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

    private: 
     member1 member1_; 
     member2 member2_; 
} 

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

Questo produrrà simili avvertimenti. Il motivo è che in C++ il costruttore costruisce sempre le classi base nell'ordine mostrato nell'elenco della classe base (base1 seguito da base2), quindi costruisce le variabili membro dall'alto verso il basso nella definizione della classe. Lo fa senza riguardo per l'ordine in cui specifichi le cose nella lista di inizializzazione del tuo membro - questo ordine è ignorato, ma se non corrisponde ad alcuni compilatori (incluso il tuo sembra) ti avviserà a riguardo.

Il motivo è che C++ ha il requisito rigoroso che i distruttori vengano chiamati nell'ordine inverso dei costruttori, quindi se facesse le cose nell'ordine delle liste di inizializzazione dei membri dovrebbe in qualche modo "ricordare" "quale costruttore era stato chiamato così da poter chiamare i distruttori nell'ordine giusto. Non lo fa, ma invece usa sempre lo stesso ordine.