一.构造函数与析构函数在对象创建与删除时的执行顺序
构造函数:按照继承顺序依次执行父类的构造函数,再执行子类的构造函数,析构函数:和构造函数完全相反;这个跟栈的先存后释放弹夹模型是一个道理
这里面有个逻辑是,对象创建时,子类会自动先调用父类的构造函数,
析构时,子类自己的析构函数执行完会自动调用父类的析构函数;但是反过来就不会了。所以就会用到虚析构函数;
二.虚析构函数
在实际调用对象时,我们经常会用父类的指针去操作子类的函数功能,这个时候delete父类的指针后,只会执行父类的析构函数,而子类里的析构函数不会执行所以会造成内存泄露。
当我们把父类(也即基类)的析构函数加上virtual,则delete父类的指针时调用的是子类的析构函数,加上子类的析构函数调用完后会自动调用父类的析构函数,这样就可以将父类和之类的析构函数都调用,能够将内存全部清理掉。
具体实例代码如下:
#include<iostream>
#include<string>
using namespace std;
string GetMyString()
{
return "This is a string";
}
class zheng
{
private:
int a;
public:
zheng() { a = 0;
cout << "initional construct" << endl; };
zheng(zheng& z){
cout << "Lvalue copy construct" << endl;
}
zheng(zheng && z){
cout << "Rvalue copy construct" << endl;
}
zheng(const int&& x):a(x){
cout << "value copy construct" << endl;
}
virtual ~zheng(){
cout << "destruct construct" << endl;
}
void set(int b)
{
a = b;
}
int get()
{
return a;
}
};
struct test1
{
private:
//zheng a;
public:
test1(){
cout << "test1 zheng costruct" << endl;
}
test1( zheng& s)
{
cout << "test1 L zheng construct" << endl;
}
test1( zheng&& s)
{
cout << "test1 R zheng construct" << endl;
}
~test1(){
cout << "test1 zheng destruct" << endl;
}
// int get()
// {
// return a.get();
// }
};
struct test:public test1, zheng
{
private:
//zheng a;
public:
test(){
cout << " zheng costruct" << endl;
}
test( zheng& s)
{
cout << "L zheng construct" << endl;
}
test( zheng&& s)
{
cout << "R zheng construct" << endl;
}
~test(){
cout << " zheng destruct" << endl;
}
// int get()
// {
// return a.get();
// }
};
int main(int argc, char const *argv[])
{
test *p = new test;
zheng *p1 = p;
delete p1;
cout << "123" << endl;
return 0;
}
执行结果如下:
当虚析构函数 = 0 时,代表着这个虚构函数不能被调用,也就是不能虚构,不能释放内存,进而它这个类也就不能被其它的类继承了。