2012-06-04 3 views
4

프로그래밍 과제를 수행하는 동안 기본 C++ 개념보다 문제가있는 것으로 보입니다. 내 프로그램에서 버그를 발견하고 그것이 내 소멸자가 예상했던 것보다 더 많은 시간 동안 실행 되었기 때문입니다. 다음은 내가 잘못하고있는 것을 보여주는 코드 샘플입니다. 맨 아래 필수 사항입니다. 나는 일이 기대C++ : 소멸자가 두 번 실행되는 이유는 무엇입니까?

#include <iostream> 
using namespace std; 

class A 
{ 
public: 
    A(int num) 
    { 
     number = num; 
     cout << "A constructed with number " << number << ".\n"; 
    } 
    ~A() 
    { 
     cout << "A destructed with number " << number << ".\n"; 
    } 
private: 
    int number; 
}; 

class B 
{ 
public: 
    B(A pa) 
     : a(pa) 
    { 
     cout << "B constructor run.\n"; 
    } 
    ~B() 
    { 
     cout << "B destructor run.\n"; 
    } 
private: 
    A a; 
}; 


int main() 
{ 
    A foo(7); 
    { 
     B bar(foo); 
    } 
    //Pause the program. 
    system("pause"); 
} 

A foo(7);7를 전달 생성자를 foo를라는 A 객체의 스택에 공간을 할당하고 전화입니다. 7number에 할당하고 생성자가 실행되었음을 나타내는 출력을 인쇄합니다. 이제 B bar(foo);bar이라는 B 개체에 대해 스택에 공간을 할당하고 foo을 값으로 전달하는 생성자를 호출합니다.이 값은 int의 컨테이너 일뿐입니다. 생성자는 전달 된 A 매개 변수를 자신의 개인 데이터 멤버 a에 할당하고 출력을 화면에 출력합니다. bar이 닫는 중괄호의 범위를 벗어나면

지금, 그때의 데이터 멤버, 즉 A a에 대한 소멸자를 호출 화면에 출력을 인쇄하는 bar의 소멸자를 호출 할 것으로 예상된다. 소멸자는 출력을 화면에 출력하고 포함하고있는 int number을 버립니다. 나는 출력해야 기대

:

A constructed with number 7. 
B constructor run. 
B destructor run. 
A destructed with number 7. 
//Destructors should be called in the reverse order of their construction right? 

실제 출력 :

A constructed with number 7. 
B constructor run. 
A destructed with number 7. //This is unexpected. 
B destructor run. 
A destructed with number 7. 

추가 파괴하는 것이 원인이 무엇입니까?

+3

시끄러운 복사 생성자도 만드십시오. –

+0

[규칙 3] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – rlduffy

+0

가능한 복제본을 확인하십시오 [클래스의 소멸자가 두 번 호출 된 이유는 무엇입니까?] (http : // stackoverflow.com/questions/2627540/why-is-the-destructor-of-the-class-called-twice) –

답변

1

분명히 그것은 회원 데이터 A a에서 비롯됩니다. B 클래스의 기본 copy-ctor로 생성 되었기 때문에 A에서 생성 된 출력을 보지 않는 것이 좋습니다. 클래스 A에 대해 하나의 copy-ctor를 추가하는 것이 좋습니다. 그러면 생성자가 표시됩니다. 순서.

A(const A& a) 
{ 
    number = a.number; 
    cout << "A copy-constructed with number " << number << ".\n"; 
} 
0

클래스 B에는 하나의 멤버가 있기 때문에 A a 이므로 B 개체를 먼저 소멸시키고 멤버의 소멸자를 먼저 호출해야합니다.

1

사람들이 "foo"및 "bar"로 귀여워지면 나는 그것을 싫어합니다.

하지만 두 인스턴스 "A"가 생성되는 것을 볼 수 있습니다. 하나는 명시 적으로, 다른 하나는 암시 적으로 "B"로 구성됩니다. 그리고 두 명의 소멸자가 불러들입니다.

이 사진에 대해 좋지 않은 점은 무엇입니까?

2

B 생성자 foo 다음 멤버 a 복사 얻는다 파라미터 pa에 복사하는 것을 의미하는 값으로 A 객체 걸린다. 컴파일러는 복사본 중 하나 (생성자에 대한 인수) 중 하나를 제거 할 수 있지만 다른 하나는 생략 할 수 없으며 두 번째 객체 인 A이 파괴됩니다.

관련 문제