생성자 초기화 목록 평가 순서


252

인수를 취하는 생성자가 있습니다. 나는 그것들이 나열된 순서대로 구성되었다고 가정했지만, 어떤 경우에는 반대로 구성되어 중단을 초래하는 것으로 보입니다. 인수를 되 돌리면 프로그램 중단이 중지되었습니다. 이것은 내가 사용하는 구문의 예입니다. 문제는이 경우 a_를 b_ 전에 초기화해야한다는 것입니다. 건설 순서를 보장 할 수 있습니까?

예 :

class A
{
  public:
    A(OtherClass o, string x, int y) :
      a_(o), b_(a_, x, y) { }

    OtherClass a_;
    AnotherClass b_;
};

6
생성자 인수에 대해 질문하고 있지만 생성자에 도달하기 전에 평가되며 지정되지 않은 컴파일러 결정 순서로 평가됩니다. 그러나 초기화 목록의 순서에 대해 정말로 묻기 때문에 질문 제목을 변경했습니다.
Rob Kennedy

답변:


278

클래스의 멤버 변수 선언 순서에 따라 다릅니다. 그래서 a_다음, 첫 번째가 될 것입니다 b_귀하의 예제에서 두 번째로 하나가 될 것입니다.


22
실제로 선언에서 생성자 이니셜 라이저 목록과 다른 순서가 있으면 좋은 컴파일러가 경고합니다. 예를 들어 -Wreordergcc를 참조하십시오 .
Greg Hewgill

236
이들이 생성자 순서가 아닌 멤버 선언 순서로 구성되는 이유는 생성자가 여러 개일 수 있지만 소멸자가 하나뿐이기 때문입니다. 그리고 소멸자는 구축 순서에 따라 멤버를 파괴합니다.
AProgrammer

3
우리는 ... 선언 순서를 의미 했습니까? "건설"이 아니라, 소멸자는 생성자를보고 그것을 알 수 없습니까?
콘래드 B

196

설명을 위해 표준을 인용하려면 :

12.6.2.5

초기화는 다음 순서로 진행됩니다.

...

  • 그런 다음 비 정적 데이터 멤버는 클래스 정의에서 선언 된 순서대로 초기화됩니다 (다시 mem-initializer의 순서에 관계없이).

...


18

이에 대한 표준 참조 는 이제 12.6.2 섹션 13.3으로 보입니다.

(13.3) — 그런 다음 정적이 아닌 데이터 멤버는 클래스 정의에서 선언 된 순서대로 초기화됩니다 (다시 mem-initializer의 순서에 관계없이).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.