【05】了解C++默默编写并调用那些函数
1、如果没有声明copy构造方法,copy赋值操作符,和析构方法,编译器会自动生成这些方法,且是inline。
2、如果没有声明任何构造方法,编译器会自动生成一个default构造方法,且是inline。
3、编译器总是为我们生成一个合成析构方法。
4、首先考虑,编译器生成的copy构造方法做什么事?
copy构造方法是一个特殊的构造方法,形参是const T&。编译器生成的copy构造方法逐个成员初始化。逐个成员初始化:对于创建对象的每个non-static字段,使用现有对象的字段去初始化。
如果字段是类类型,递归调用类的copy构造方法。如果是内置类型,逐个bit拷贝。需要注意的是:对于引用和指针,复制引用和指针。不同类型的指针,指明了指向对象的类型,但是指针本身是int类型,就是一个地址,引用是用指针实现出来的。因此,对于引用和指针,也是逐个bit拷贝,因为它们本身的类型是int。
还有一个特殊的情况:类中的数组。一般情况下,数组是不能赋值的,但是类中的数组是可以复制的,逐个元素进行拷贝。
对于编译器生成的copy构造方法,可以这样认为:在初始化列表中,使用现有对象的每个字段去初始化正在创建对象的字段。
5、编译器生成的copy赋值操作符做什么事?
copy赋值操作符,就是重载了操作符=,返回T&,形参是const T&。编译器生成的copy赋值操作符逐个成员赋值。逐个成员赋值:对于当前对象的每个non-static字段,使用rhs的字段进行赋值。那么问题来,
我们知道,类中的有些字段是只能初始化,不能赋值的,也就是不能修改。包括:类中的引用和const字段,这种情况下,编译器不会为我们生成copy赋值操作符。
还有一种情况,父类的copy赋值操作符是private,编译器也不会为子类生成copy赋值操作符。为什么?因为子类期望调用父类的copy赋值操作符,对父类的成分赋值,由于父类的copy赋值操作符是private,不能调用,编译器也就不为子类生成copy赋值操作符了。
6、可以认为有两个析构方法:析构方法和合成析构方法。前者用于释放动态获取的资源,后者用于按对象创建的逆序撤销每个non-static字段。对象超出作用域,先调用析构方法,再调用合成析构方法,在合成析构方法中,对于类类型,递归调用它的析构方法和合成析构方法,对于内置类型,不需要做什么。
有个三法则:如果类需要析构方法,那么它也需要自定义copy构造方法和copy赋值操作符。为什么?怎么理解?
析构方法,用于释放动态获取的资源,定义了析构方法,说明类中有指针。在上文中,我们知道,指针本身是int类型,copy构造和copy赋值的时候,只是拷贝指针值,并没有拷贝指向的对象,这就导致两个对象中的指针,指向同一块数据,这往往不是程序员所期望的。因此,需要自定义copy构造和copy赋值,对指向的数据也进行拷贝,也就是深拷贝。
7、编译器生成的default构造方法,成员初始化列表为空,这就意味着,类中的内置类型字段没有被初始化。为了保证对象被使用之前,先被初始化,这情况下需要提供一个构造方法,对内置类型的字段初始化。
【05】了解C++默默编写并调用那些函数的更多相关文章
- Effective C++ -----条款05:了解C++默默编写并调用哪些函数
面对“内含reference成员或者含const成员”的class内支持赋值操作,你必须自己定义copy assignment操作符. 如果某个base classes将copy assignment ...
- 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 ...
- 条款05:了解C++默默编写并调用哪些函数
每一个class都会有一个或多个构造函数.一个析构函数.一个copy assignment操作符.这些控制着基础操作,像是产出新对象并确保它被初始化.摆脱旧对象并确保它被适当清理.以及赋予对象新值. ...
- effective c++(05)(06)之c++默默编写并调用的函数
1. 当只写一个空类的时候,编译器会为他声明一个copy构造函数,一个copy assignment函数和一个析构函数.如下: 如果写下: class Empty{ }; 编译器就会实现以下代码: c ...
- Effective C++条款05:了解C++默默编写并调用哪些函数
class Empty{}; class Empty{ Empty(){}; Empty(const Empty& rhs){}; ~Empty(){}; Empty& operato ...
- [Effective C++ --005]了解C++默默编写并调用哪些函数
<前言>编译器是个十分敬业的工作者,不但为你编译代码,甚至为你生成代码,不可思议吧.本文主要介绍编译器究竟会为我们生成和调用哪些代码. <空类和非空类>如果问什么样的类是空类? ...
- 了解 C++ 默默编写并调用的函数
前言 对于一个类来说,最最基础的三类成员函数莫过于:构造函数,析构函数以及拷贝函数 (copy构造函数和=重载函数).即使你的类没有为这些函数做出定义,C++ 也会自动为你创建.本文将讲述的是 C++ ...
- C++编译器默默编写并调用哪些函数
什么时候empty class(空类)不再是个empty class呢?当C++处理过它之后,是的,如果你自己没有声明,编译器就会为它声明(编译器版本)一个copy构造函数.一个copy assign ...
随机推荐
- code forces Jeff and Periods
/* * c.cpp * * Created on: 2013-10-7 * Author: wangzhu */ #include<cstdio> #include<iostrea ...
- easyui源码翻译1.32--ComboTree(树形下拉框)
前言 扩展自$.fn.combo.defaults和$.fn.tree.defaults.使用$.fn.combotree.defaults重写默认值对象.下载该插件翻译源码 树形下拉框结合选择控件和 ...
- 接口 --- Java
package com.test2; public class Test { public static void main(String[] args) { // TODO Auto-generat ...
- 【Linux安全】防止 root 用户远程登录
防止 root 用户远程登录,在终端输入以下命令: vim /etc/ssh/sshd_config 修改如下行为:no PermitRootLogin no 如图所示:
- FRM-40401 No changes to save error
FAQ: I have updated a table from the form and written a update statement in the when-button-pressed ...
- linux 失败无连接 检查电缆吗
将BOOTPROTO=dhcp改成 BOOTPROTO=static 改成手动获取IP的模式 原因: 虚拟机中的Linux目前是默认设成的自动获取IP设置,但你的网络中没有DHCP服务,所以会显示“正 ...
- C#程序中访问配置文件
在C#编程中,有时候会用到配置文件,那么该如何在程序中获取或修改配置文件中的相关数据呢?下面采用一个简单的C#控制台程序来说明. 新建一个C#控制台程序,打开“解决方案资源管理器”,如下图: 可以看到 ...
- wildfly9 配置SSL单向认证/https
D:\>keytool -genkey -keystore cdi-init.keystore -alias cdi-init -keyalg RSA -keysize 2048 -validi ...
- 学习Python前序
最近一直在学习有关Python语言.回顾的时候,发现学习过程中的有些东西被遗漏了.故记录在此......加深记忆,方便查找. The reason: 语言如此多,why choose Pyth ...
- MongoDB(索引及C#如何操作MongoDB)(转载)
MongoDB(索引及C如何操作MongoDB) 索引总概况 db.test.ensureIndex({"username":1})//创建索引 db.test.ensureInd ...