教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 文库大全 > 实用文档 >

五、析构函数和this指针

来源:网络收集 时间:2026-09-11
导读: C++经典 一、析构函数 前面的一些例子都没有说明析构函数,这是因为所用到的类在结束时不需要做特别的清理工作。下面的程序给出了一新的Date类,其中包括一个字符串指针,用来表示月份。 #include iostream.h #include string.h class Date { int mo,da,yr;

C++经典

一、析构函数
前面的一些例子都没有说明析构函数,这是因为所用到的类在结束时不需要做特别的清理工作。下面的程序给出了一新的Date类,其中包括一个字符串指针,用来表示月份。

#include iostream.h
#include string.h

class Date
{
int mo,da,yr;
char *month;
public:
Date(int m=0, int d=0, int y=0);
~Date();
void display() const;
};

Date::Date(int m,int d,int y)
{
static char *mos[] =
{
January,February,March,April,May,June,
July,August,September,October,November,December
};
mo=m; da=d; yr=y;
if(m!=0)
{
month=new char[strlen(mos[m-1])+1];
strcpy(month, mos[m-1]);
}
else month = 0;
}

Date::~Date()
{
delete [] month;
}

void Date::display() const
{
if(month!=0) cout<<month<<' '<<da<<','<<yr;
}

int main()
{
Date birthday(8,11,1979);
birthday.display();
return 0;
}

在Date对象的构造函数中,首先用new运算符为字符串month动态分配了内存,然后从内部数组中把月份的名字拷贝给字符串指针month。
析构函数在删除month指针时,可能会出现一些问题。当然从这个程序本身来看,没什么麻烦;但是从设计一个类的角度来看,当Date类用于赋值时,就会出现问题。假设上面的main()修改为“
int main()
{
Date birthday(8,11,1979);

Date today;
today=birthday;

birthday.display();
return 0;
}

这会生成一个名为today的空的Date型变量,并且把birthday值赋给它。如果不特别通知编译器,它会简单的认为类的赋值就是成员对成员的拷贝。在上面的程序中,变量birthday有一个字符型指针month,并且在构造函数里用new运算符初始化过了。当birthday离开其作用域时,析构函数会调用delete运算符来释放内存。但同时,当today离开它的作用域时,析构函数同样会对它进行释放操作,而today里的month指针是birthday里的month指针的一个拷贝。析构函数对同一指针进行了两次删除操作,这会带来不可预知的后果。
如果假设today是一个外部变量,而birthday是一个自变量。当birthday离开
其作用域时,就已经把对象today里的month指针删除了。显然这也是不正确的。
再假设有两个初始化的Date变量,把其中一个的值赋值给另一个:
Date birthday(8,11,1979);
Date today(12,29,2003);
today=birthday;

C++经典

问题就更复杂了,当这两个变量离开作用域时,birthday中的month的值已经通过赋值传递给了today。而today中构造函数用new运算符给month的值却因为赋值被覆盖了。这样,birthday中的month被删除了两次,而today中month却没有被删除掉。

二、重载赋值运算符
为了解决上面的问题,我们应该写一个特殊的赋值运算符函数来处理这类问题。当需要为同一个类的两个对象相互赋值时,就可以重载运算符函数。这个方法可以解决类的赋值和指针的释放。
下面的程序中,类中的赋值函数用new运算符从堆中分配了一个不同的指针,该指针获取赋值对象中相应的值,然后拷贝给接受赋值的对象。
在类中重载赋值运算符的格式如下:
void operator = (const Date&)
后面我们回加以改进。目前,重载的运算符函数的返回类型为void。它是类总的成员函数,在本程序红,是Date类的成员函数。它的函数名始终是operator =,参数也始终是同一个类的对象的引用。参数表示的是源对象,即赋值数据的提供者。重载函数的运算符作为目标对象的成员函数来使用。

#include iostream.h
#include string.h

class Date
{
int mo,da,yr;
char *month;
public:
Date(int m=0, int d=0, int y=0);
~Date();
void operator=(const Date&);
void display() const;
};

Date::Date(int m, int d, int y)
{
static char *mos[] =
{
January,February,March,April,May,June,
July,August,September,October,November,December
};
mo = m; da = d; yr = y;
if (m != 0)
{
month = new char[strlen(mos[m-1])+1];
strcpy(month, mos[m-1]);
}
else month = 0;
}

Date::~Date()
{
delete [] month;
}

void Date::display() const
{
if (month!=0) cout<<month<<' '<<da<<,<<yr<<endl;
}

void Date::operator=(const Date& dt)
{
if (this != &dt)
{
mo = dt.mo;
da = dt.da;
yr = dt.yr;
delete [] month;
if (dt.month != 0)
{
month = new char [std::strlen(dt.month)+1];
std::strcpy(month, dt.month);
}
else month = 0;
}
}

int main()
{
Date birth
day(8,11,1979);
birthday.display();

Date newday(12,29,2003);
newday.display();

newday = birthday;
newday.display();

return 0;
}


C++经典

除了为Date类加入了一个重载运算符函数,这个程序和上面的一个程序是相同的。赋值运算符函数首先取得所需的数据,然后用delete把原来的month指针所占用的内存返还给堆。接着,如果源对象的month指针已经初始化过,就用new运算符为对象重新分配内存,并把源对象的month字符串拷贝给接受方。
重载的Date类赋值运算符函数的第一个语句比较了源对象的地址和this指针。这个操作取保对象不会自己给自己赋值。

三、this指针
this指针是一个特殊的指针,当类的某个非静态的成员函数在执行时,就会存在this指针。它指向类的一个对象,且这个对象的某个成员函数正在被调用。
this指针的名字始终是this,而且总是作为隐含参数传递给每一个被声明的成员函数,例如:
void Date::myFunc(Date* this);
实际编程时函数的声明不需要包含这个参数。
当程序中调用某个对象的成员函数时,编译器会把该对象的地址加入到参数列表中,感觉上就好象函数采用了上面所示的声明,并且是用如下方式来调用的:
dt.myFunc(& dt);
静态成员函数不存在this指针。
当调用某个对象的成员函数时,编译器把对象的地址传递给this指针,然后再调用该函数。因此,成员函数你对任何成员的调用实际上都隐式地使用了this指针。
1.以this指针作为返回值
使用this指针可以允许成员函数返回调用对象给调用者。前面的程序中重载赋值运算符没有返回值,因此不能用如下的形式对字符串进行赋值:
a=b=c;
为了使重载的类赋值机制也能这样方便,必须让赋值函数返回赋值的结果,在这里就是目标对象。当赋值函数执行时,其返回值也恰好是thi …… 此处隐藏:4227字,全部文档内容请下载后查看。喜欢就下载吧 ……

五、析构函数和this指针.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wenku/1802071.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)