欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Effective C++ 条款5、6、7

程序员文章站 2022-07-12 17:51:40
...

条款5 了解C++默默编写并调用哪些函数

1、默认构造函数    Empty();

2、拷贝构造函数    Empty(const Empty& rhs){...}

3、拷贝赋值操作符    Empty& operator=(const Empty& rhs){}   (但凡赋值(或赋值复合)操作符都是返回reference to *this,见条款10)

4、析构函数    ~Empty(){...}

5、针对移动构造函数Empty(Empty&& rhs){...},只要自定义了析构函数,编译器就不会自动合成移动构造函数因为对于基本类型来说是"复制"而非真正的移动,只要其一析构了,另外一个的资源也就没了.所以只要定义了析构函数,就不会合成移动构造~)。

6、针对移动赋值操作符Empty& operator=(Empty&& rhs),理由同上。

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

拒绝的方式有如下两种:

1、只需要将copy构造函数或copy赋值操作符在private中声明即可——从而编译器会方动拒绝调用它们(因为default构造、copy构造和copy赋值函数是编译器自动生成的函数)

2、当然,在C11标准中,可以使用如Empty(const Empty& rhs)=delete;方式,明确拒绝调用此copy构造函数。

3、选择私有继承像Uncopyable这样的base class是一种非常精彩的运用。

class Uncopyable {
protected:
	Uncopyable(){}
	~Uncopyable(){}
private:
	Uncopyable(const Uncopyable&);
	Uncopyable& operator=(const Uncopyable);
};
//用法如下
class HomeForSale:private Uncopyable{};//class不再用声时copy构造函数或copy assginment操作符

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

1、C++明确指出,当derived class对象经由一个base class指针被删除,而该bass class带着一个non-virtual析造函数,其结果未有定义(也就是说实际执行时通常发生的是对象的derived成分没有被销毁)。

解决办法很简单:给bass class一个virtual析构函数。

2、class不含virtual函数,通常表示它并不意图被用做一个base class。当class不企图被当作base class令其析构函数为virtual往往是一个馊主意(书上虽讲解的很明白,但还是似懂非懂,所以还是默认此准则,“馊主意”)。

说直接一点就是,析构函数需要virtual关键字时,才添加,否则不要画蛇添足。

使用心得:当class内含至少一个virtual函数时,才为析构函数声明为virtual函数。

3、继承一个类,但此类的析构函数没有virtual关键字修饰,同样是件灾难事情(见下面灾难代码)。所以STL库中的类,绝不用来派生其他类。

class SpecialString :public string {};//绝对是一个馊主意,因为string有个non-virtual析构函数
SpecialString* pss = new SpecialString("Impending Doom");
string* ps;
...
ps = pss;//SpecialString* => string*
...
delete ps;//未有定义!现实中*ps的SpecialString资源会泄漏,因为SpecialString析构函数没被调用

以下内容均来自Scott Meyers大师所著Effective C++ version3,如有错误地方,欢迎指正!相互学习,促进!!