2010-05-02 130 views
5

我有一套代碼,它模仿了一個基本的圖書館編目系統。有一個名爲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 

回答

28

當您在一個類中聲明成員變量時,它們將按照您聲明的順序進行初始化。但是你可以在你的構造函數的初始化列表中以任何順序編寫它們。例如,

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的值將是未定義的。

+0

非常感謝你 – silent 2010-05-02 05:05:41

+0

很好的答案,謝謝。 – 2013-04-10 05:58:27

3

當您在構造函數中初始化類成員時,請按照聲明它們的相同順序對它們進行初始化。例如: -

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

Foo()構造,交換的ab順序會導致你的警告。初始化基類也是一樣的(如果在任何數據成員初始化之前調用它的構造函數,則應該調用它的構造函數)。

6

你需要看看你的構造函數和成員初始化列表。這是棘手的說沒有看到代碼,但正在發生的事情是,你有這樣的代碼: -

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++嚴格要求析構函數按照構造函數的相反順序調用,所以如果它按照成員初始化列表的順序執行,它必須以某種方式「記住「哪個構造函數已被調用,以便它可以按正確的順序調用析構函數。它不這樣做,而是總是使用相同的順序。