11
#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
}; 
class derv :public base 
{ 
    int b; 
    public: 
    derv() {b =1;} 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

나는 derv 클래스에 가상 소멸자가 없으며, derv 객체의 기본 부분 만 삭제합니까 ??가상 소멸자없이 메모리 누수가 발생할 가능성이 있습니까?

+0

가상 소멸자가 필요한 기본 클래스입니다. – Yuushi

+0

@ 신비로운 : 제임스는 이것을 가지고있다. – Puppy

+0

@James, 당신도 기본 클래스에는 가상 함수가 없지만 기본 클래스를 상속 받기를 원하면 가상 소멸자가 있어야한다고 말했습니까? – Alok

답변

19

수 있습니다.

base에는 가상 소멸자가 없으므로 코드에는 정의되지 않은 동작이 표시됩니다. 무엇이든 일어날 수 있습니다. 예상대로 작동하는 것 같습니다. 메모리가 누출 될 수 있습니다. 프로그램이 중단 될 수 있습니다. 하드 드라이브를 포맷 할 수 있습니다.

인용이 요청되었습니다.

삭제 대상물의 정적 유형이 동적 유형 다르면 : 스칼라 delete 식 (즉, 식 아닌 delete[])에 대한 C++ 11 §5.3.5/3 주 정적 유형은 삭제할 객체의 동적 유형의 기본 클래스이고 정적 유형은 가상 소멸자를 가져야하거나 동작이 정의되지 않습니다.

정지형 (base)은 동적 유형 (derv) 가상 소멸자가없는 정지형 상이하므로 동작이 정의되지 않는다.

+2

가상 소멸자가 기본에 없다는 것은 파생 클래스의 소멸자에 지정된 사용자 지정 finalization이 실행되지 않는다는 것을 의미합니다. 객체의 메모리는 여전히 올바르게 할당 해제됩니다. ('base'의 소멸자는 가상이 아닌 것으로 정의 된 경우에도 호출됩니다.) – Xion

+6

@ Xion : 정말. 동작은 정의되지 않습니다. 모든 배팅은 꺼져 있습니다. 프로그램의 행동에 대해 확실하게 말할 수있는 것은 없습니다. –

+2

참고로하시기 바랍니다. – wilhelmtell

-1

코드에 메모리 누수가 없습니다. 파생 클래스 소멸자에서 일부 메모리를 확보해야하는 경우 메모리 누출이있었습니다.

+6

동작은 정의되지 않습니다. 모든 배팅은 꺼져 있습니다. 프로그램의 행동에 대해 확실하게 말할 수있는 것은 없습니다. –

-1

동적으로 생성 된 멤버 변수가 없으므로 소스 코드에 메모리 누수가 없습니다. 'B'가 동적으로 작성되기 때문에, 출력이 될 것이다 이때

#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
    ~base() 
    { 
     cout<<"\nBase Destructor called"; 

    } 
}; 
class derv :public base 
{ 
    int *b; 

    public: 
    derv() { b = new int;} 
    ~derv() 
    { 
     cout<<"\nDerv Destructor called"; 
     delete b; 
    } 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

메모리 누수가이 경우

Base Destructor called 

:

는 케이스 (1) 아래의 변형 예를 생각해 'delete'키워드를 사용하여 삭제해야하는 'new'를 사용합니다. derv 소멸자가 호출되지 않으므로 삭제되지 않으므로 메모리 누수가 발생합니다. 이 호출 DERV 소멸자 leak.because에는 메모리없는 및 B지고 이때 2 출력 될 경우

#include <iostream> 
using namespace std; 
class base 
{ 
    int a; 
public: 
    base() {a =0;} 
    virtual ~base() 
    { 
     cout<<"\nBase Destructor called"; 

    } 
}; 
class derv :public base 
{ 
    int *b; 

    public: 
    derv() { b = new int;} 
    ~derv() 
    { 
     cout<<"\nDerv Destructor called"; 
     delete b; 
    } 
}; 
int main() 
{ 
    base *pb = new derv(); 
    delete pb; 
} 

,

Derv Destructor called 
Base Destructor called 

:

는 아래 케이스 (2)를 고려 삭제됨

파생 클래스는 가상 클래스로 정의하여 파생 클래스 객체를 가리키는 기본 클래스 포인터를 삭제할 때 파생 클래스 소멸자가 호출되도록 할 수 있습니다.

파생 클래스가 동적으로 멤버를 만들었 으면 '소멸자가 가상이어야합니다'라고 말할 수 있습니다.

+1

동작이 정의되지 않았습니다. 모든 배팅은 꺼져 있습니다. 프로그램의 행동에 대해 확실하게 말할 수있는 것은 없습니다. –

+1

@JamesMcNellis : 파생 클래스에서 메모리 할당이 위의 코드에서 가상 소멸자가 있어야합니다. 그렇지 않으면 메모리 누수가 있습니다. –