답변:
아니오, 소멸자는 반대 순서로 자동 호출됩니다. (기본 수업 마지막). 기본 클래스 소멸자를 호출하지 마십시오.
delete
클래스에 대한 포인터를 두 번 호출 해도 세그먼트 오류가 발생하는 이유는 무엇입니까?
기본 소멸자를 호출 할 필요는 없습니다. 파생 소멸자가 항상 기본 소멸자를 호출합니다. 파괴 명령에 대해서는 여기 관련 답변을 참조하십시오 .
기본 클래스에서 가상 소멸자를 원하는 이유를 이해하려면 아래 코드를 참조하십시오.
class B
{
public:
virtual ~B()
{
cout<<"B destructor"<<endl;
}
};
class D : public B
{
public:
virtual ~D()
{
cout<<"D destructor"<<endl;
}
};
할 때 :
B *pD = new D();
delete pD;
그런 다음 B에 가상 소멸자가 없으면 ~ B () 만 호출됩니다. 그러나 가상 소멸자가 있으므로 ~ D ()가 먼저 호출되고 ~ B ()가 호출됩니다.
다른 사람들이 말한 것 외에도 파생 클래스에서 소멸자를 가상으로 선언 할 필요는 없습니다. 기본 클래스에서와 마찬가지로 소멸자를 가상으로 선언하면 파생 된 모든 소멸자가 선언 여부에 관계없이 가상이됩니다. 다시 말해:
struct A {
virtual ~A() {}
};
struct B : public A {
virtual ~B() {} // this is virtual
};
struct C : public A {
~C() {} // this is virtual too
};
아니요, 기본 클래스 소멸자를 호출하지 마십시오. 다른 사람들이 지적한 것처럼 항상 자동으로 호출되지만 결과가있는 개념 증명이 있습니다.
class base {
public:
base() { cout << __FUNCTION__ << endl; }
~base() { cout << __FUNCTION__ << endl; }
};
class derived : public base {
public:
derived() { cout << __FUNCTION__ << endl; }
~derived() { cout << __FUNCTION__ << endl; } // adding call to base::~base() here results in double call to base destructor
};
int main()
{
cout << "case 1, declared as local variable on stack" << endl << endl;
{
derived d1;
}
cout << endl << endl;
cout << "case 2, created using new, assigned to derive class" << endl << endl;
derived * d2 = new derived;
delete d2;
cout << endl << endl;
cout << "case 3, created with new, assigned to base class" << endl << endl;
base * d3 = new derived;
delete d3;
cout << endl;
return 0;
}
출력은 다음과 같습니다.
case 1, declared as local variable on stack
base::base
derived::derived
derived::~derived
base::~base
case 2, created using new, assigned to derive class
base::base
derived::derived
derived::~derived
base::~base
case 3, created with new, assigned to base class
base::base
derived::derived
base::~base
Press any key to continue . . .
기본 클래스 소멸자를 가상으로 설정하면 사례 3 결과는 사례 1 및 2와 같습니다.
C ++의 소멸자는 Base 클래스 소멸자가 선언 될 때만 생성 순서 (Derived then Base)로 자동 호출 됩니다 .virtual
그렇지 않은 경우 객체 삭제시 기본 클래스 소멸자 만 호출됩니다.
예 : 가상 소멸자가없는 경우
#include <iostream>
using namespace std;
class Base{
public:
Base(){
cout << "Base Constructor \n";
}
~Base(){
cout << "Base Destructor \n";
}
};
class Derived: public Base{
public:
int *n;
Derived(){
cout << "Derived Constructor \n";
n = new int(10);
}
void display(){
cout<< "Value: "<< *n << endl;
}
~Derived(){
cout << "Derived Destructor \n";
}
};
int main() {
Base *obj = new Derived(); //Derived object with base pointer
delete(obj); //Deleting object
return 0;
}
산출
Base Constructor
Derived Constructor
Base Destructor
예 : 기본 가상 소멸자 사용
#include <iostream>
using namespace std;
class Base{
public:
Base(){
cout << "Base Constructor \n";
}
//virtual destructor
virtual ~Base(){
cout << "Base Destructor \n";
}
};
class Derived: public Base{
public:
int *n;
Derived(){
cout << "Derived Constructor \n";
n = new int(10);
}
void display(){
cout<< "Value: "<< *n << endl;
}
~Derived(){
cout << "Derived Destructor \n";
delete(n); //deleting the memory used by pointer
}
};
int main() {
Base *obj = new Derived(); //Derived object with base pointer
delete(obj); //Deleting object
return 0;
}
산출
Base Constructor
Derived Constructor
Derived Destructor
Base Destructor
기본 클래스 소멸자를 virtual
그렇지 않으면 선언 하지 않는 것이 좋습니다 . 정의되지 않은 동작이 발생합니다.
참조 : 가상 소멸자