C++构造/析构/赋值运算(05-12条款)

05 :了解C++默默编写并调用哪些函数

编译器可以暗自为class创建默认构造函数、拷贝构造函数(初始化调用)、拷贝赋值操作符(赋值调用)、析构函数·

类名(){...
类名(const 类名& rhs){...}
~类名(){...}
类名& operator=(const 类名& rhs){...}

06:若不想使用编译器自动生产的函数,就该明确拒绝

为了阻止编译器自动生产函数:自行声明函数
为了防止别人调用:声明为private
为了防止友元函数和成员函数调用:只定义不实现
为驳回编译器自动提供的机能,可将相应的成员函数声明为private并且不予实现

07:为多态基类声明virtual析构函数

  • 带有多态性质的基类应该声明一个virtual析构函数。如果类带有任何virtual函数,它就更应该拥有一个virtual析构函数。
  • 类的设计目的如果不是作为基类使用,或不是为了具备多态性,就不该声明virtula析构函数。

08:别让异常逃离析构函数

原因:析构函数吐出异常,会使程序过早结束或出现不明确的行为。比如:销毁十个成员对象,在销毁第一个的时候出现异常,这会使后面的成员对象没有被销毁就退出程序了。

  • 析构函数绝对不能吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下它们或结束程序。
  • 如果需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。

09:绝不在构造和析构过程中调用virtual函数

当基类在构造函数调用纯虚函数,在创建派生类对象时,会先调用基类的构造函数,由于基类构造函数调用了纯虚函数,同时又因基类构造期间virtual函数不会下降到派生类阶层(基类构造期间,virtual不是virtual),基类函数没有实现,进而导致派生类对象无法创建。(可能回报错:找不到函数的实现代码)。

  • 在构造和析构期间不要调用virtual函数,因为这类调用从不下降至派生类

10:令operator=返回一个reference to *this

...
类名& operator=(const 类名& rhs)
{
	...
	return *this;
}
  • 这个协议适用于所有赋值相关运算
  • 这仅仅是个协议,并无强制性,你可以不遵循它。然而这个协议被所有内置类型和STL提供的类型共同遵循。
  • 令赋值操作符返回一个reference to *this

11 在operator=中处理自我赋值

例子:pa和pb是指向同一个对象的指针,有如下语句:

pa = pb;
//赋值函数
operator =(const xxx& rhs)
{
delete m_p;
m_p = new XXX(*rhs.m_p)
return *this;
}

operator=中一般会先删除自己的成员对象(如果有),使用传入的对象(别名)创建一个相同的对象,赋给该类的成员对象变量,然后返回this。发现自己持有一个指针指向一个已被删除的对象
解决方法:
1.证同测试-判断是否是自我赋值,如果是直接返回
this
缺陷:如果创建成员对象中new异常,之前的成员也被删除了,又没创建成功,这样的指针有问题。
2.先创建对象,再删除
缺陷:自我赋值的效率问题,如果将证同测试加进来,会增加新的控制分支,代码也会变长,也会降低执行速度。
3.copy and swap-先复制副本,再将this和副本交换。

  • 确保当对象自我赋值时operator=有良好行为,技术包括以上三种
  • 确保任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。

12:复制对象勿忘其每一个成分

当基类中添成员对象时,必须同时修改拷贝函数(拷贝函数和拷贝赋值函数),发生继承,一定在派生类拷贝构造函数后加上:baseClass(rhs)调用父类的构造函数;拷贝赋值函数体里加上baseClass::operator=(rhs)。

  • Copying函数应该确保复制对象内的所有成员变量及所有基类成分
  • 不要尝试以某个拷贝函数实现另一个拷贝函数,应该将两个共同的代码放进第三个函数中,并由拷贝函数共同调用,消除代码重复。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值