effective c++第二篇

C++构造与析构深入解析
本文深入探讨C++中构造、析构、赋值运算的细节,包括编译器自动生成函数的行为,如何避免默认函数的陷阱,正确处理多态基类的析构,以及在构造和析构过程中调用虚函数的问题。同时,强调了在赋值运算符中处理自我赋值的重要性,确保代码的安全性和效率。

第二篇:构造、析构、赋值运算

条款05:了解c++默默编写,并调用哪些函数

  • 编译器可以给类自动创造default构造、copy构造函数、析构、copy assignment操作符函数
  • 前提是你缺省了这些函数的声明和定义
  • 在类内如果有引用类型(referrence)和const类型的成员变量的话,编译器不会提供默认的赋值操作符函数,需要自己写

6.若不想使用编译器自动生成的函数,就该明确拒绝

  • 将函数声明为private,以copy构造函数和赋值操作符为例,声明为private就可以阻止类外部调用,从而可以实现禁止拷贝的操作。
  • 上述方法,成员函数和友元函数还是能调用,还不是完全安全的,所有有一个实践上的推荐,就是声明为private,声明但是不实现。
  • 第二种方法,是声明一个base class,该class继承自base class,base class中的构造函数和copy assignment操作符函数为private,那么要是调用改class的构造函数或赋值操作符,编译器会去调用base class中的相应函数,因为是private所以被阻止。
class BaseClass
{
	private:
		BaseClass(const BaseClass&);
		BaseClass& operator=(const BaseClass&);
};
class ChildClass:public BaseClass{
};
  • 而且你并不一定需要public继承,而且BaseClass的析构也不一定要是virtual

7.为多态基类声明virtual析构函数

  • 这点比较好理解,分为一下2点
  • 带多态性质的base class,需要一个virtual析构函数。如果一个类有一个virtual函数的话,那么就是希望它成为一个base class,它就应该有一个virtual析构。
  • 反之,如果一个class的设计目的不是为了成为base class,或者不是为了具备多态性,那么这个类就不需要virtual函数和virtual析构。
  • virtual析构的作用:一个父类指针指向一个子类对象,如果父类析构不是virtual,delete父类指针,只能销毁父类的内存,不能销毁子对象的内存,造成内存泄漏;若父类析构就可以解决这个问题,析构是从最深层的子类析构开始,往上调。

8.析构函数不要处理异常

  • 析构函数不能吐出异常,因为这样可能导致程序异常结束,资源未正常释放
  • 析构函数绝对不要吐出异常。如果一个被析构调用的函数吐出异常,析构应该捕捉异常,然后吞掉异常或结束程序。
  • 如果程序一定要对某异常做出反应,那么因该由普通函数去做,而不是析构函数。

9.绝不在构造和析构过程调用virtual函数

  • 原因:因为它永远不会下降到derived class,调用的函数base class的函数
  • 另一好理解的说法:在base class构造期间,virtual函数不是virtual函数。
  • 解决:如果想向base class构造函数传数据,可以在derived class构造函数初始化列表内,初始化base class构造函数,并传数据进去。

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

  • 为什么?要想能连续赋值,就需要这样,这也是一个习惯约定。
class Test;
Test& operator=(const Test&);
  • 这个约定也适用于所有的与赋值操作符相关的操作
Test& operator=(int rhs);

11.在operator=中处理自我赋值

class Test{};
Test t;
t=t;
  • 上面就是自我赋值,这是合法的
Test* p1=t;
Test* p2=t;
*p1=(*p2);
  • 虽然p1,p2不是一个变量,但是他们指向同一个对象,这丫是潜在的自我赋值
  • 类似的,数组元素间的赋值也可能是自我赋值。比如:a[i]=a[j], 当i=j的时候
  • 解决办法:加上证同测试,如下:
Test& operator=(const Test& rhs){
	if(this ==&rhs) return *this;
	//....
}
  • 确定任何函数如果操作多个对象,而其中有多个对象是同一个对象时,其行为一定正确。可能出现的最典型的错误就是delete对象一次以上

12.复制对象时,勿忘记每个成分

  • coping函数时,勿忘记对象内所有成员变量和base class里的成员变量
  • 不要使用一个coping函数实现另一个coping函数,要将共同机能放在一个函数内,再分别调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值