2016-10-19 7 views
-1

가정하자 파라미터.생성자 다음 I 클래스가

class B{ 
    int y ; 
    A obj_a ; 
    B(int j , A a){ 
     y = j ; 
     obj_a = a ; 
    } 
} 

다음 작업을 수행 할 때 :

int main(){ 
     A obj1(1) ; // obj.x has value 1 
     B obj2(2 , obj1) ; 
    } 

제 2 라인의 형식은 A의 어떤 함수 호출을 말하는없는 오류가 발생 :: A(). 이것은 기본 스타일 생성자가 누락되었음을 의미하는 것을 알지만, 왜 이것을 필요로합니까? obj1은 정의 된 생성자를 사용하여 생성되므로 문제가되지 않습니다.

현재 내 생각으로는 A a이고 obj_a = a은 암시 적으로 정의 된 복사 생성자를 호출합니다.

참고 : 간결하게하기 위해 비공개, 공개 등을 제외했습니다.

+1

후 실제 오류. 당신의 고객이 아마도'const int i'이어야한다고 불평 할 것입니다; – stark

+1

명시 적으로 이니셜 라이저 목록을 사용하지 말 것을 요청했습니다. – kfsone

답변

1

개체가 완전히 일치해야는 모든 구성원은이 들어가는 시간, 건설 생성자의 본문입니다.

{ 
    y = j ; 
    obj_a = a ; 
} 

아무것도 할 수있는 기회를 얻을 전에

B(int j , A a){ 
    y = j ; 
    obj_a = a ; 
} 

에 그래서, obj_a이 구성되어 있어야합니다. obj_a을 구성하는 방법에있는 명령이 Member Initializer List 제공되지 않았기 때문에

, obj_a는 클래스 A의 기본 생성자로 구축됩니다. 클래스 A에는 기본 생성자가없고 A::A()이 없으므로 오류가 발생합니다.

해결 방법은 함수 본문 내에 할당 대신 Member Initializer List를 사용하는 것입니다. 이렇게하면 즉시 작성 될 객체의 생성을 줄일 수있을뿐 아니라 컴파일러는 최적화 할 수있는 방법이 더 많아지고 다른 작은 개선이 이루어질 수 있습니다.

클래스 B은 다음과 같아야합니다

class B{ 
    int y ; 
    A obj_a ; 
    B(int j , A a): y(j), obj_a(a) 
    { 
    } 
} 
+0

이 값으로 생성 된 객체 'a'입니까? 참조로 전달할 수 있습니까? –

+0

@AbhinavVishak'a'는 현재 값으로 전달되고 아마도 사본이 필요할 것입니다. 예, 'a'를 참조로 전달할 수 있습니다. – user4581301

3

obj_a = a은 복사 생성자가 아니라 operator=입니다. 문제는 obj_a은 초기화 생성자 목록에서 호출 할 생성자를 지정하지 않았기 때문에 기본 생성자 을 사용하여 초기화됩니다.

B(int j , A a) /*: obj_a{}*/ { /*...*/ } 
       ^^^^^^^^^^^^^ 
      implicit call to default constructor 

당신은 명시 적으로 멤버 초기화 목록에서 하나 개의 인자로 생성자를 호출 할 수 있습니다

B(int j , A a) : obj_a{ a } { /*...*/ } 
+0

문제는'obj_a = a'로 그다지 문제가되지 않습니다. 매개 변수 목록 안에있는'A a'. 어떻게 수정해야합니까? –

+1

@AbhinavVishak'A a'는 ** 매개 변수 목록에있을 때 ** 문제가 아닙니다. 문제는 mem-initialiser리스트 (':'다음의리스트)에'obj_a'가 없다는 것입니다. – Angew

+0

@agnew 당신이 제안한 변경 사항을 수행했고 컴파일합니다. 감사 ! 나는 이니셜 라이저 목록을 사용하는 것에 대해 아직도 혼란 스럽다. 나는': obj_a {a}'를 사용한 후에'obj_a = a'가 필요 없다고 생각합니다. ?? –