Effective C++_笔记_条款05_了解C++默认编写并调用哪些函数

(整理自Effctive C++,转载请注明。整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/

直接上代码:

   1: class Empty{};

如果你写了这样一个空类,你没有声明任何函数,编译器会声明一个default构造函数、copy构造函数、copy赋值操作符和一个析构函数。相当于你写下:

   1: class Empty
   2: {
   3: public:
   4:     Empty(){...} //default构造函数
   5:     Empty(const Empty& rhs){...} //copy构造函数
   6:     Empty& operator=(const Empty& rhs)//copy赋值操作符
   7:     ~Empty(){...}//析构函数
   8: };

这些函数的作用:

(1)default构造函数和析构函数:主要是给编译器一个地方用来放置“藏身幕后”的代码,像是调用base
classes和non-static成员变量的构造函数和析构函数。注意:编译器产出的析构函数是non-virtual的,除非这个类的base
class自身声明virtual析构函数。

(2)至于copy构造函数和copy赋值操作符,编译器创建的版本只是单纯地将来源对象的每个non-static成员变量拷贝到目标对象。

一般来说,copy赋值操作符和copy构造函数的行为基本上是一致的。但如果你打算在一个“内含reference成员”的class内支持copy赋值操作符,你必须自己定义它。因为要进行赋值操作,就相当于对reference赋值,但是C++并不允许让reference改指不同对象,reference初始化后就不能改变了;面对“内含const成员”的class,编译器的反应也是一样的,更改const成员是不合法的;还有一种情况:如果base class
将copy赋值操作符声明为private,编译器拒绝为其derived
classes生成copy赋值操作符,编译器想要为派生类生成的copy赋值操作符处理base class
成分,但它无法调用派生类无权调用的成员函数。

总结:

(1)编译器可以自动为class创建default构造函数、copy构造函数、copy赋值操作符,以及析构函数。

时间: 2024-10-12 07:51:08

Effective C++_笔记_条款05_了解C++默认编写并调用哪些函数的相关文章

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

1. 成员函数只有被需要(被调用)才必须有定义,同理,只有当默认构造函数,拷贝构造函数,赋值操作符,析构函数被需要而类定义它们时,它们才会被编译器创建出来(除非函数在基类中被声明为虚函数,编译器产生的函数是非虚的,public的). 2. 并不是只要类没有定义默认构造函数,拷贝构造函数,赋值操作符时编译器就会自动合成它们,它们只有在"被需要"的时候才被产生. (具体见http://www.cnblogs.com/reasno/p/4742322.html) 3. 虽然编译器在类的创建者

[effictive c++]条款05 了解c++默默编写并调用哪些函数

c++的编译器是非常智能的!当你声明一个空类empty class,如果你的代码有用到这个empty class时,编译器会默默的为你编写一些基本的函数.那么究竟编译器自己添加的函数都有哪些呢?构造函数,析构函数,一个copy构造函数和一个copy assignment操作符.举个例子来说明一下,如果你写下: class empty{}; 就好像你写下这样的代码: class Empty { public: Empty(){ ... } //default 构造函数 ~Empty(){ ....

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

当写下如下空类时: class Empty{}; 编译器处理后变成: class Empty { public: Empty() {}//默认构造函数 Empty(const Empty&) {}//默认拷贝构造函数 ~Empty(){}//默认析构函数 Empty& operator=(const Empty&) {}//默认赋值操作符 }; 编译器产出的析构函数是一个non-virtual版本,除非这个class的base class自身声明有virtual析构函数. 编译器产

Effective C++_笔记_条款08_别让异常逃离析构函数

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) C++并不禁止析构函数吐出异常,但它不鼓励你这样做.考虑如下代码: 1: class Widget{ 2: public: 3: ... 4: ~Widget() {...} //假设这个可能吐出一个异常 5: }; 6:  7: void doSomething() 8: { 9: vector<Widget> v ; //v在这里被自动销毁 10: ...

Effective C++_笔记_条款12_复制对象时勿忘其每一个成分

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 编译器会在必要时候为我们的classes创建copying函数,这些“编译器生成版”的行为:将被烤对象的所有成员变量都做一份拷贝. 如果你声明自己的copying函数,意思就是告诉编译器你并不喜欢缺省实现中的某些行为.编译器仿佛被冒犯似的,会以一种奇怪的方式回敬:当你的实现代码几乎必然出错时却不告诉你.所以自己实现copying函数时,请遵循一条规则:如果你为c

Effective C++_笔记_条款11_在operator=中处理“自我赋值”

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果:所谓“别名”就是“有一个以上的方法指涉对象”.一般而言如果某段代码操作pointers或references而它们被用来“指向多个相同类型的对象”,就需要考虑这些对象是否为同一个.实际上两个对象来自同一个继承体系,它们甚至不需要声明为相同类型就可能造成“别名”.因为一个base class的refe

Effective C++ 阅读笔记_条款27 尽量少做转型动作

Effective C++ 阅读笔记_条款27 尽量少做转型动作 1.转型的三种形式,可以分为两大类. (1)旧式转型(old-style casts) (1.1) (T) expresstion (1.2) T (expression) (2) 新式转型(c++-style casts) (2.1)const_cast<T> (expression) (2.2)dynamic_cast<T> (expression) (2.3)reinterpret_cast<T>

Effective C++_笔记_条款07_为多态基类声明virtual析构函数

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 这个规则只适用于polymorphic(带多态性质的)base class身上.这种base class的设计目的是为了用来“通过base class接口处理derived class对象”.假如我们在程序中设计factory(工厂)函数,让它返回base class指针,指向新生成的derived class对象,假设base class有个non-virtu

Effective C++_笔记_条款09_绝不在构造和析构过程中调用virtual函数

(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为方便采用书上的例子,先提出问题,在说解决方案. 1 问题 1: class Transaction{ 2: public: 3: Transaction(); 4: virtual void LogTransaction() const = 0 ; 5: ... 6: }; 7:  8: Transaction::Transaction() //Base cl