Item 5:那些被C++默默地声明和调用的函数 Effective C++笔记
来源:互联网 发布:mac绝对路径 编辑:程序博客网 时间:2024/05/22 13:06
Item 5: Know what functions C++ silently writes and calls
在C++中,编译器会自动生成一些你没有显式定义的函数,它们包括:构造函数、析构函数、复制构造函数、=
运算符。 有时为了符合既有设计,我们不希望自动生成这些函数,我们可以把它们显式声明为private
。 此时在使用这些类的客户看来,它们就像不存在一样。
class Empty{public: // 默认构造函数 Empty(){} // 拷贝构造函数 Empty(const Empty& rhs){} // 析构函数 ~Empty(){} // 赋值运算符 Empty& operator=(const Empty& rhs){}};
这些编译器自动生成的缺省方法是可以禁用的,把它们声明为private
便能解决绝大多数问题。 更多的讨论可以参考:Item 6: 禁用那些不需要的缺省方法-Effective C++笔记
调用时机
当我们没有显式地定义上述这四种函数时,编译器会自动帮我们定义。这些函数它们调用的时机如下:
- 构造函数:对象定义;使用其他兼容的类型初始化对象时(可使用
explicit
来避免这种情况) - 复制构造函数:用一个对象来初始化另一对象时;传入对象参数时;返回对象时;
- 析构函数:作用域结束(包括函数返回)时;
delete
=
运算符:一个对象赋值给另一对象
为了更清晰地说明它们的调用时机,来个例子吧:
Empty e1; // 默认构造函数Empty e2(e1); // 拷贝构造函数Empty e3 = e1; // 拷贝构造函数e2 = e1; // = 运算符void func(Empty e){ // 拷贝构造函数,拷贝一份参数对象 return e; // 拷贝构造函数,拷贝一份返回对象 // 析构函数,拷贝得到的参数对象被析构}e2 = func(e1); // = 运算符 // 析构函数,返回值被析构
引用成员
当对象包含引用成员时,拷贝和赋值行为将会变得非常有趣,考虑这样一个类:
class Person{public: string & name; Person(string& str): name(str){ }};string s1 = "alice", s2 = "bob";Person p1(s1), p2(s2);s1 = s2;
赋值后,p1.name
会指向p2.name
吗?我们知道在C++中引用本身是不可修改的。 即使p1.name
指向了p2.name
,那么对p1.name
的赋值将会影响到p2
? 于是,C++拒绝编译上述代码,此时我们需要手动定义一个赋值运算符。
说来神奇,拷贝构造函数也存在同样的问题,编译器却从不抱怨。可以正常编译,并且两个引用指向同一对象。
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/07/23/effective-cpp-5.html
0 0
- Item 5:那些被C++默默地声明和调用的函数 Effective C++笔记
- Effective C++(5) 了解C++默默地编写并调用哪些函数
- Effective Modern C++: Item 12 -> 声明覆盖函数override
- c语言函数的声明和调用
- 《Effective C#》Item 5:提供一个有意义的ToString函数
- 《Effective C#》Item 5:提供一个有意义的ToString函数
- [翻译] Effective C++, 3rd Edition, Item 5: 了解 C++ 为你偷偷地加上和调用了什么函数
- <Effective C++> Item 9:绝不在构造和析构过程中调用虚函数
- Effective c++(笔记) 之 类与函数的设计声明中常遇到的问题
- 《Effective C#》Item 18:Dispose函数的标准实现模式
- 《Effective C#》Item 18:Dispose函数的标准实现模式
- Item 7:将多态基类的析构函数声明为虚函数 Effective C++笔记
- 《Effective C++》笔记之C++中定义和声明的区别
- Effective Modern C++: Item 5 -> 优先选择auto而不是显式类型声明
- C语言:返回指针的函数,函数声明、定义和调用,嵌套调用
- Objective-C的方法声明和调用
- Effective C++(四)设计和声明
- <<Effective C++>>笔记5
- 记录下log4j的两种配置方式
- 《MYSQL必知必会》读书笔记
- NSURLSession的使用和用其实现断点续传
- 各种扩展名的证书
- C++对象内存布局
- Item 5:那些被C++默默地声明和调用的函数 Effective C++笔记
- 1096. Consecutive Factors (20)
- 冲吧!不必准备好
- httpd: unrecognized service 的解决方案
- Mysql 转换表的引擎
- leetcode: (21) Merge Two Sorted Lists
- [leetcode-257]Binary Tree Paths(java)
- Item 6:禁用那些不需要的缺省方法 Effective C++笔记
- android studio模板