2012-10-12 3 views
2
#include <iostream> 
using namespace std; 

class Exem { 
    int *a; 

    public: 
     Exem() { a = new int; *a = 0; }; 
     Exem (int x) { a = new int; *a = x; }; 

     ~Exem() { delete a; }; 

     int f (void); 

     Exem operator+ (Exem); 
}; 

int Exem::f (void) { 
    return *a * 2; 
} 

Exem Exem::operator+ (Exem nimda) { 
    Exem aux; 

    *aux.a = *a + *nimda.a; 

    return aux; 
} 

int main() { 
    Exem adabo(1); 
    Exem inakos(2); 

    adabo = adabo + inakos; 

    cout << adabo.f(); 
    cin.get(); 
} 

이것은 내 코드이며 문제를 보여주기위한 클래스입니다. main()의 출력은 이론적으로 '6'이지만 실제 나타나는 모든 것은 무의미한 숫자입니다.Dev-C++ 및 코드 :: 블록에서 망가는 소멸자

이것은 분명히 클래스의 소멸자와 관련이 있습니다.이 소멸자는 내가 이해 한 것으로부터 연산자 + 함수의 끝에 너무 일찍 호출됩니다. 실제로는 전달되기 전에 잃게됩니다. ~ Exem()은 주석을 달았을 때 예상대로 프로그램을 실행할 수 있기 때문에 그러한 결론에 도달했습니다.

필자는 Embarcadero RAD Studio에서 똑같은 코드를 컴파일하려고했을 때이 두 컴파일러와 관련이 있다고 생각합니다.

답변

2

동적으로 할당 된 멤버 변수가 있으므로 Exem에 대한 복사 생성자 및 할당 연산자를 명시 적으로 정의해야합니다.

클래스에 대해 복사 생성자 및 할당 연산자가 명시 적으로 정의되지 않은 경우 컴파일러에서 동적 버전을 할당 한 클래스에 적합하지 않은 기본 버전을 생성합니다. 기본 생성 된 버전이 적합하지 않은 이유는 구성원의 단순 복사본을 수행하기 때문입니다. Exem의 경우 인스턴스가 Exem 인 두 개 이상의 인스턴스가 복사 될 때 동일한 동적 할당 된 int 구성원 인 a을 가리키고 있습니다. 인스턴스 중 하나가 파괴되면 해당 adelete d, 그리고 dangling 포인터 및 정의되지 않은 동작으로 다른 인스턴스를 둡니다.

rule of three을 참조하십시오.

Exem에 대한 간단한 수정은 intint*에서 변화 a 될 것이다. 기본 복사 생성자, 대입 연산자 및 소멸자가 정확합니다. 그것의 인수를 변경하지 않는 한 Exem::operator+()const Exem& 매개 변수를 사용한다고


참고.

관련 문제