2010-05-04 5 views
2

저는 이니셜 라이저 목록을 사용하여 다음과 같이 몇 번 실행 했으므로 잘 설명하지 못했습니다. 사람이 (내가 오타를 잡을 수있는 컴파일러, 그래서 나와 함께 부담하지 않습니다) 다음과 같은 실패 이유를 정확히 설명 할 수 :생성자 이니셜 라이저에있는 멤버의 멤버 함수를 사용합니다.

class Foo 
{ 
public: 
    Foo(int i) : m_i(i) {} //works with no problem 

    int getInt() {return m_i;} 

    ~Foo() {} 
private: 
    int m_i; 
}; 

class Bar 
{ 
public: 
    Bar() : 
    m_foo(5),   //this is ok 
    m_myInt(m_foo.getInt()) //runtime error, seg 11 
    {} 

    ~Bar() {} 
private: 
     Foo m_foo; 
    int m_myInt; 


}; 

멤버의 멤버 함수를 호출하려고 초기화 목록을 높은 초기화, 내가 할 seg faults. 나는 이것이 알려진 문제 (또는 아마도 어쨌든 디자인에 의한 것임)를 떠올리는 것처럼 보이지만 잘 묘사 된 것을 본 적이 없다. 첨부 된 예제는 일반 오래된 데이터 형식으로 고안되었지만 Bar::m_myInt을 기본 (빈) 생성자가없는 다른 개체로 대체하면 문제가 더욱 현실적입니다. 누구나 나를 계몽시킬 수 있습니까?

+1

'~ Foo() {}'에 대해 Typo :'~ Foo {}'? –

+0

이것은 Cygwin에서 오류없이 GCC 3.4.3을 사용하여 컴파일되고 실행됩니다. 어떤 컴파일러를 사용하고 있습니까? – andand

답변

9

초기화 순서는 초기화 목록의 요소 순서와 관계가 없습니다. 실제 순서는 클래스 정의에있는 멤버의 순서입니다. 즉, m_foo은 초기화 목록이 아니기 때문에 m_myInt보다 먼저 초기화되지만 멤버가 클래스에 처음으로 표시되기 때문입니다.

게시 한 구체적인 예는 문제없이 컴파일하고 실행해야합니다.

+2

gcc의 경우,'-Wreorder'를 넘길 수 있습니다. –

+0

이 엉망이라면 경고합니다. 내 머리가 바뀌 었어. 초기화 순서가 클래스 정의 순서가 아닌 초기화 프로그램 목록 순서를 기반으로한다고 생각했습니다. 그 문제를 해결해 주셔서 감사합니다! – awm129

3

데이터 멤버는 클래스 선언 (예제에서는 private: 아래의 순서)에 나열된 순서로 초기화됩니다. 이니셜 라이저 목록에 주어진 순서에는 구성 순서가 없습니다.

private: 
    int m_myInt; 
    Foo m_foo; 

당신이 표시된 것보다 데이터 멤버의 순서가 다른 실제 것을 가능 :

따라서, 귀하의 예제에서, 그래서 같은 데이터 멤버는 정의되지 않은 동작이 발생할 수 있습니다 재정렬?

+0

예, 내 사례에는 문제를 완전히 설명하기 위해 바의 비공개 멤버가 있어야합니다. 당신의 도움을 주셔서 감사합니다! – awm129

관련 문제