条款05:了解C++默默编写并调用哪些函数
每一个class都会有一个或多个构造函数、一个析构函数、一个copy assignment操作符。这些控制着基础操作,像是产出新对象并确保它被初始化、摆脱旧对象并确保它被适当清理、以及赋予对象新值。
那么当你当你编写了一个empty class的时候,当你利用编译器的对代码进行处理的时候,它其实已经并非是一个empty class 了。编译器会悄悄的给你生成了default 构造函数、一个析构函数、一个copy构造函数和一个copy assignment操作符,并且它们都是inline的(隐式inline)。如下代码示例
一个自定类: class empty{};
其实等于以下代码:
class Empty {
public:
Empty() { }//default 构造函数
~Empty() { }//析构函数
Empty(const Empty& rhs) { }//copy构造函数
Empty& operator=(const Empty& rhs) { }//copy assignment操作符
};
注意:上面的重载的操作运算符operator=的返回值是对象的引用,条款21似乎说了不要妄想返回对象的引用,这篇文章的意思不是说不能返回对象的引用,而是当你要返回对象的引用的时候,要确定引用的本体是谁,它能否被合理的delete。
以下三种情况出现时,会调用一个类的拷贝构造函数:
1) 用一个已经实例化了的该类对象,去实例化该类的另外一个对象;
2) 用该类的对象传值的方式作为一个函数的参数;
3) 一个函数返回值为该类的一个对象。
#include <iostream> using namespace std; class Person
{
public: Person(string& a, const int& b) : name(a), id(b) { } private: const int id;
string& name; }; int main()
{
Person p1(string("chu"), 1); Person p2(string("jun"), 2); p1 = p2;/////// error C2582: 'operator =' function is unavailable in 'Person' system("pause"); return 0;
}
还有一种情况编译器不会生成copy assignment函数,就是基类将copy assignment声明为private,派生类型就无法获得编译器的帮助,因为编译器为derived classes所生成的copy assignment操作符要处理base class成分。因为派生类型无法调用基类型的copy assignment函数(不具备访问权限)。
#include <iostream> using namespace std; class BaseClass
{ private: BaseClass& operator=(const BaseClass& rhs) { } }; class derived : public BaseClass { }; int main()
{ BaseClass px1, px2; px1 = px2; ///// 'BaseClass::operator =' : cannot access private member declared in class 'BaseClass' system("pause");
return 0; }
所以,请记住:
编译器可以暗自为class创建default构造函数,copy构造函数,copy assignment操作符,以及析构函数。
条款05:了解C++默默编写并调用哪些函数的更多相关文章
- Effective C++ -----条款05:了解C++默默编写并调用哪些函数
面对“内含reference成员或者含const成员”的class内支持赋值操作,你必须自己定义copy assignment操作符. 如果某个base classes将copy assignment ...
- Effective C++ 条款05:了解C++编写并调用哪些函数
规则一 编译器默认操作 // 你认为 class Empty { }; // 实际上 class Empty { public: Empty() { ... } // default 构造函数 Emp ...
- Effective C++ 条款五 了解C++默默编写并调用哪些函数
//申明一个类时,编译器会默认为你提供四个函数. //无参构造函数,析构函数,copy构造函数,copy assignment操作符. template <typename T> ...
- EC笔记,第二部分:5.了解C++默默编写并调用哪些函数
5.了解C++默默编写并调用哪些函数 1.C++空类 C++会为一个空类建立以下函数 (1).默认构造函数 (2).默认拷贝构造函数 (3).析构函数 (4).赋值运算符(如果成员包含引用类型或con ...
- Effective C++ 之 Item 5:了解C++默默编写并调用哪些函数
Effective C++ chapter 2. 构造 / 析构 / 赋值运算 (Constructors, Destructors, and Assignment Operators) Item 5 ...
- Effective C++条款05:了解C++默默编写并调用哪些函数
class Empty{}; class Empty{ Empty(){}; Empty(const Empty& rhs){}; ~Empty(){}; Empty& operato ...
- effective c++(05)(06)之c++默默编写并调用的函数
1. 当只写一个空类的时候,编译器会为他声明一个copy构造函数,一个copy assignment函数和一个析构函数.如下: 如果写下: class Empty{ }; 编译器就会实现以下代码: c ...
- 【05】了解C++默默编写并调用那些函数
1.如果没有声明copy构造方法,copy赋值操作符,和析构方法,编译器会自动生成这些方法,且是inline. 2.如果没有声明任何构造方法,编译器会自动生成一个default构造方法,且是inlin ...
- 条款5.了解c++默默编写并且调用了哪些函数。
如果想在一个内含reference成员的class内支持赋值操作,必须自己定义copy assignment操作符.而且面对“内含有const成员的”class,编译器的反应也是相同的,由于更改con ...
随机推荐
- nyoj 138 找球号(二)(哈希)
题目:nyoj——138 /*** 哈希求解...采用链表保存 插入时,可以去除重复 查找 找到该组,然后在改组的查找 当这个组不存在时或是没有找到时是 NO 其他是YES 1e6+1 时间最短 */ ...
- oracle查询字符集语句
(1)查看字符集(三条都是等价的) 复制代码 代码如下: select * from v$nls_parameters where parameter='NLS_CHARACTERSET'sel ...
- DOCTYPE声明的几种类型
DOCTYPE声明的几种类型 DOCTYPE 声明决定着浏览器怎么去解析和渲染当前页面,所以对于页面来说是很重要的. HTML5时代,统一用 <!DOCTYPE html> 这样简单的方式 ...
- XmlDocument加载有Xmlns的xml文档,使用Xpath
using System; using System.IO; using System.Xml; public class Sample { public static void Main() { X ...
- 什么是epoll
什么是epoll epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改进的poll.当然,这不是2.6内核才有的,它是在2.5.44内核中被引进的(epoll(4) is a new A ...
- xmu1125 越野车大赛(三分)
1125: 越野车大赛 Time Limit: 500 MS Memory Limit: 64 MB Special JudgeSubmit: 4 Solved: 3[Submit][Statu ...
- Android 开发佳站【转】
Android控件拖动 这里演示控件拖动的动画: 原理就是响应控件的Touch事件,在Touch事件中对移动进行处理,注意,一定要在布局文件中设置控件的 android:clickable=& ...
- 关于js封装框架类库之属性操作
在对DOM对象操作时,往往都要涉及到其属性的操作,为了提高开发效率,同时兼顾浏览器的性能,在这简单的封装了几个常见的属性.因为是模块化,在这只是引入了部分代码,其他代码在前几篇模块封装中有写.如有不足 ...
- Java 网络编程(二) 两类传输协议:TCP UDP
链接地址:http://www.cnblogs.com/mengdd/archive/2013/03/09/2951841.html 两类传输协议:TCP,UDP TCP TCP是Transfer C ...
- PHP CI框架最近学到的内容
CI框架配置方面注意的细节 在config里面的database.php里面是和数据库配置相关的内容 $db['default'] = array( 'dsn' => '', 'hostname ...