最近在设计几个c++类,有个问题不是很清晰啦所以写个小列子测试一下。测试代码如下:
class Interface
{
public:
Interface()
{
qDebug("Interface Constructor");
}
~Interface()
{
qDebug("Interface Destructor");
}
};
class Base : public Interface
{
public:
Base()
{
qDebug("Base Constructor");
}
~Base()
{
qDebug("Base Destructor");
}
virtual void function(void) = 0;
};
class Derive : public Base
{
public:
Derive()
{
qDebug("Derive Constructor");
}
~Derive()
{
qDebug("Derive Destructor");
}
void function()
{
qDebug()<<"function";
}
};
main函数为:
Derive *base = new Derive;
qDebug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
delete base;
打印输出为:
Interface Constructor
Base Constructor
Derive Constructor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Derive Constructor
Base Destructor
Interface Destructor
说明构造的时候是先构造基类,按顺序构造派生类,析构的时候与之相反(所有的c++书籍都会讲到)。
如果我把main函数改为:
Base *base = new Derive;
qDebug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
delete base;
打印输出为:
Interface Constructor
Base Constructor
Derive Constructor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Base Destructor
Interface Destructor
是的构造的时候是构造了3个层次,而析构却析构了两个,这样会内存泄漏。
如果想main函数不变而不内存泄漏要怎么改呢?
类修改成这样:
class Interface
{
public:
Interface()
{
qDebug("Interface Constructor");
}
~Interface()
{
qDebug("Interface Destructor");
}
};
class Base : public Interface
{
public:
Base()
{
qDebug("Base Constructor");
}
virtual ~Base()//注意这里变成虚函数即可
{
qDebug("Base Destructor");
}
virtual void function(void) = 0;
};
class Derive : public Base
{
public:
Derive()
{
qDebug("Derive Constructor");
}
~Derive()
{
qDebug("Derive Destructor");
}
void function()
{
qDebug()<<"function";
}
};
输出为:
Interface Constructor
Base Constructor
Derive Constructor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Derive Destructor
Base Destructor
Interface Destructor
经测试Base和Interface只要有一个析构函数是虚的就会是这样的输出,但是如果只是Derive是虚析构函数是不行的,应该按照delete类往上找(继承的顺序)只要发现有一个是虚函数就会析构真正的new出来的类。
如果Base的构造和析构用默认的,结果和Base的构造和析构不是虚函数一样的效果,也说明啦,默认的是非虚的。
如果多重继承又会是什么样呢?
代码:
class Interface
{
public:
Interface()
{
qDebug("Interface Constructor");
}
virtual ~Interface()
{
qDebug("Interface Destructor");
}
};
class Base : public Interface
{
public:
Base()
{
qDebug("Base Constructor");
}
~Base()
{
qDebug("Base Destructor");
}
virtual void function(void) = 0;
};
class Base2
{
public:
Base2()
{
qDebug("Base2 Constructor");
}
~Base2()
{
qDebug("Base2 Destructor");
}
};
class Derive : public Base, public Base2
{
public:
Derive()
{
qDebug("Derive Constructor");
}
~Derive()
{
qDebug("Derive Destructor");
}
void function()
{
qDebug()<<"function";
}
};
输出为:
Interface Constructor
Base Constructor
Base2 Constructor
Derive Constructor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Derive Destructor
Base2 Destructor
Base Destructor
Interface Destructor
有输出可知:构造的顺序是从左至右深度优先的,而析构与之相反。
此时将main函数改为:
Base2 *base = new Derive;
qDebug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
delete base;
输出为:
Interface Constructor
Base Constructor
Base2 Constructor
Derive Constructor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Base2 Destructor
尽管Interface的析构是虚函数,但是并不在Base2的层次上所以,此时必须改为Base2为虚函数才正确。
以上内容其实是比较简单的,记录一下备忘,刚开始做c++开发慢慢总结,以上代码在linux下qt环境内测试。gcc环境为
gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)