2010-05-02 2 views
5

나는 기본적인 라이브러리 목록 시스템을 모방 한 일련의 코드를 가지고있다. items라는 이름의 기본 클래스가 있는데 여기에는 일반 ID, 제목 및 연도 변수가 정의되고 기타 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

+0

감사합니다. –

3

생성자에서 클래스 멤버를 초기화 할 때 선언 된 순서와 동일한 순서로 초기화합니다. 예컨대 : 당신의 경고로 이어질 것 ab의 순서를 전환 Foo() 생성자에서

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

. 기본 클래스 (명시 적으로 호출 된 경우 해당 생성자가 데이터 멤버 초기화 프로그램보다 먼저 호출되어야 함)를 초기화하는 경우에도 마찬가지입니다.

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++에는 생성자의 역순으로 소멸자를 호출해야한다는 엄격한 요구 사항이 있습니다. 따라서 멤버 초기화 목록 순서대로 작업을 수행하면 "어떻게해야합니까? "어느 생성자가 소멸자를 올바른 순서로 호출 할 수 있도록 호출 되었습니까? 이 작업을 수행하지는 않지만 대신 항상 동일한 순서를 사용합니다.