高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(3[VC/C++编程]
本文“高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(3[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
9.3 构造和析构的次序
构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用成员对象的构造函数.析构则严峻按照与构造相反的次序履行,该次序是唯一的,不然编译器将无法自动履行析构历程.
一个风趣的现象是,成员对象初始化的次序完好不受它们在初始化表中次序的影响,只由成员对象在类中声明的次序决意.这是因为类的声明是唯一的,而类的构造函数可以有多个,因此会有多个差别次序的初始化表.假如成员对象按照初始化表的次序举行构造,这将招致析构函数无法得到唯一的逆序.[Eckel, p260-261]
9.4 示例:类String的构造函数与析构函数
// String的普通构造函数
String::String(const char *str)
{
if(str==NULL)
{
m_data = new char[1];
*m_data = ‘\0’;
}
else
{
int length = strlen(str);
m_data = new char[length+1];
strcpy(m_data, str);
}
}
// String的析构函数
String::~String(void)
{
delete [] m_data;
// 由于m_data是内部数据范例,也可以写成 delete m_data;
}
9.5 不要轻蔑拷贝构造函数与赋值函数
由于并非全部的对象城市利用拷贝构造函数和赋值函数,程序员大概对这两个函数有些轻蔑.请先记着以下的告诫,在阅读正文时就会多心:
u 本章开首讲过,假如不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝”的方法自动生成缺省的函数.假使类中含有指针变量,那么这两个缺省的函数就隐含了错误.以类String的两个对象a,b为例,假定a.m_data的内容为“hello”,b.m_data的内容为“world”.
现将a赋给b,缺省赋值函数的“位拷贝”意味着履行b.m_data = a.m_data.这将造成三个错误:一是b.m_data原有的内存没被释放,造成内存泄露;二是b.m_data和a.m_data指向同一块内存,a或b任何一方变更城市影响另一方;三是在对象被析构时,m_data被释放了两次.
u 拷贝构造函数和赋值函数非常简单混合,常招致错写、错用.拷贝构造函数是在对象被成立时调用的,而赋值函数只能被已经存在了的对象调用.以下程序中,第三个语句和第四个语句很类似,你分得清楚哪个调用了拷贝构造函数,哪个调用了赋值函数吗?
String a(“hello”);
String b(“world”);
String c = a; // 调用了拷贝构造函数,最好写成 c(a);
c = b; // 调用了赋值函数
本例中第三个语句的气势较差,宜改写成String c(a) 以辨别于第四个语句.
9.6 示例:类String的拷贝构造函数与赋值函数
// 拷贝构造函数
String::String(const String &other)
{
// 答应操作other的私有成员m_data
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data, other.m_data);
}
// 赋值函数
String & String::operate =(const String &other)
{
// (1) 查抄自赋值
if(this == &other)
return *this;
// (2) 释放原有的内存资源
delete [] m_data;
// (3)分配新的内存资源,并复制内容
int length = strlen(other.m_data);
m_data = new char[length+1];
strcpy(m_data, other.m_data);
// (4)返回本对象的引用
return *this;
}
类String拷贝构造函数与普通构造函数(拜见9.4节)的辨别是:在函数进口处无需与NULL举行对比,这是因为“引用”不大概是NULL,而“指针”可认为NULL.
以上是“高质量C++/C编程指南-第9章-类的构造函数、析构函数与赋值函数(3[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |