Answers:
不,析构函数将以相反的构造顺序自动调用。(最后是基类)。不要调用基类的析构函数。
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 ++ 中的析构函数才会按其构造顺序(先导出,然后继承)自动调用。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
否则会导致未定义的行为。
参考:虚拟析构函数