类4-析构和复制构造函数

类的构造函数是产生类对象,每产生一个类对象就会占用一定的内存,当类不用时,对象又是如何不再占用内存呢?

这里就会用到析构函数,即销毁类对象用到的函数。

如果一个类成员中没有析构函数,则编译器在销毁对象时会提供一个此函数进行对象销毁,把类数据成员变量从自由存储器中去除。

一. 析构函数没有返回值,也不提供任何形参。

  因此每个类只有一个析构函数。 它的命名为~加上类名即可。在类外定义时要加上类名和域名解析符。  

#include <iostream>
#include
<cstring>
using namespace std;

class CBox
{
public:
CBox();


~CBox();
};

CBox::CBox()
{
printf(
"Construct called!\n");
}


CBox::
~CBox()
{
printf(
"Destory called!\n");
}


void main()
{
CBox box[
5];

}

此时,在main中生成了5个CBox类型的对象,会调用构造函数。当在main函数执行完返回时,就会销毁对象,要调用析构函数~CBox().以下为结果:

  

如果我们在此类内动态创建一个变量,即在堆上创建一个动态变量,这时我们必须要在析构函数中要释放它,否则会产生大量的内存而无法取消,以致使内存用完。

#include <iostream>
#include
<cstring>
using namespace std;

class CShowMsg
{
private:
char* pmsg;
public:
void showIt() const
{
cout
<<endl
<<pmsg;
}

CShowMsg(
const char* text="Default message")
{
pmsg
=new char[strlen(text)+1];
strcpy(pmsg,text);
}

~CShowMsg()
{

cout
<<endl
<<"Destroy called!"
<<endl;
delete [] pmsg;
}
};

void main()
{
CShowMsg mmsg(
"My test class");
mmsg.showIt();

}

pmsg是一char指针,并在自由内存中分配了strlen(text)+1大的空间,如果在~CShowMsg()中不手工销毁,这个占用的空间是永远存在的,如果产生过多的对象时就会有很多的内存存在,这就是我们所说的内存泄露。


二、复制构造函数

  默认复制构造函数的作用是将类对象的指针成员存储的地址提制到另个对象中,因为默认复制构造函数实现的复制过程只是将原来对象的数据成员

中存储的数据复制到新对象中。

  如: CBox box1(box2);即可 box2的数据成员完整的产生一个备份给box1.如果CBox类中都只有基本数据成员,则两个对象互不影响。

 

我们看下上面CShowMsg类,如果它产生两个对象,msg1,然后用 CShowMsg msg2(msg1).看下用复制构造函数有什么影响。

此时msg2中的pmsg的指针和msg1的指针是一样的,即同时指向一个文本地址,那么当msg1或msg2销毁时,这个指针也被清空,这时另个对象也找不到了这个地址了,故如果是动态分配内存的类必须要实现自己的复制构造函数。

 注:如果动态为本地C++成员分配内存,则必须实现复制构造函数。

 以下为类自己的复制构造函数

 

#include <iostream>
#include
<cstring>
using namespace std;

class CShowMsg
{
private:
char* pmsg;
public:
void showIt() const
{
cout
<<endl
<<pmsg;
}

CShowMsg(
const char* text="Default message")
{
pmsg
=new char[strlen(text)+1];
strcpy(pmsg,text);
}

CShowMsg(
const CShowMsg& iniMsg)  /*复制构造函数,这时你会发现pmsg是开辟一个新的空间,与iniMsg的msg地址不一样,
                         可以防止默认构造函数的出错。*/
{
pmsg
=new char[strlen(iniMsg.pmsg)+1];
strcpy(pmsg,iniMsg.pmsg);
}

~CShowMsg()
{

cout
<<endl
<<"Destroy called!"
<<endl;
delete [] pmsg;
}
};

void main()
{
CShowMsg mmsg(
"My test class");
mmsg.showIt();

CShowMsg othermsg(mmsg);
mmsg.showIt();

}

显示结果:

  

 


  

posted on 2011-09-09 15:12  天上星  阅读(249)  评论(0编辑  收藏  举报

导航