更多课程 选择中心

C/C++培训
达内IT学院

400-111-8989

C++学习笔记之拷贝控制

  • 发布:C++培训
  • 来源:学习笔记
  • 时间:2017-10-16 13:14

1、一个类通过定义五种特殊的成员函数来控制此类型对象的拷贝、移动、赋值和销毁:拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符和析构函数。(拷贝、移动、析构)

2、拷贝和移动构造函数定义了当用同类型的另一个对象初始化本对象时做什么;拷贝和移动赋值运算符定义了讲一个对象赋予同类型的另一个对象时做什么;析构函数定义了当此类型对象销毁时做什么。这些操作统称为拷贝控制操作。

3、如果一个类没有定义所有这些拷贝控制成员,编译器会自动为它定义缺失的操作。

4、拷贝构造函数:构造函数的第一个参数是自身类类型的引用,并且任何额外参数都有默认值。

例子:class Foo{

public:

Foo();//默认构造函数

Foo(const Foo&);//拷贝构造函数

}

5、类对象的拷贝初始化和直接初始化:前者使用拷贝构造函数,后者使用普通的函数匹配来选择与提供的参数最匹配的构造函数。除了使用“=”之外,非引用类型参数传递,返回非引用类型的对象等都会使用拷贝初始化。

6、拷贝函数和拷贝赋值运算符:如果一个对象已经定义了,然后给对象赋值,那么就会调用拷贝赋值运算符;如果是用于创建一个对象,例如对象的初始化、非引用类型实参,非引用类型类返回值,那么就调用拷贝构造函数。它们之间的区别主要在于有无新对象的产生。详细看一下测试程序:

测试结果如下:

解析如下:

1 拷贝构造函数,用来初始化;

2 拷贝赋值运算符,用来赋值给一个已经存在的实例;

3 拷贝构造函数:值传递函数实参;

4 拷贝构造函数和拷贝赋值运算符:返回一个非引用类型的对象,以及给一个已经存在的实例赋值;

5 拷贝构造函数:返回一个非引用类型的对象,用来初始化,可以看出只执行了一遍。

1、析构函数:析构函数不接受参数,因此不能被重载。对于一个给定类,有且只有一个析构函数。

2、析构函数的组成:一个函数体+一个析构部分(implicit);所完成的工作:执行函数体,然后按照初始化成员的逆序销毁成员。在这里需要注意的是销毁成员的并不是函数体,而是析构部分。

3、三/五法则:描述了什么时候需要析构函数、拷贝构造函数和拷贝赋值操作。

1)当决定一个类的拷贝控制成员的时候,可以先从析构函数入手,因为需要析构函数的操作也需要拷贝和赋值操作。

析构函数的需求比较明显,比如需要释放一个指针的时候,就需要析构函数手动释放;假设有A和B两个对象,它们的类定义如下:

Class Person{

public:

Person(const string *name,const int age):

name(name),age(age){}

~Person{delete name;}

private:

string *name;

int age;

}

Person A("zhizhi",20);

Person B=A;

对象B由对象A使用合成拷贝构造函数而来,那么指针也是进行了拷贝操作,说明了A和B的name指针指向了同一个内存空间;那么当程序结束释放对象资源的时候,A释放name一次,这时候name已经不存在了,而B也要释放name一次,这时候就会发生错误,拷贝赋值操作类似。

所以说,需要自定义析构函数的类,也许要自定义拷贝赋值运算。

2)需要拷贝操作的类也需要赋值操作,反之亦然。但是不代表着需要析构函数。

4、可以使用=default来要求编译器生成合成的版本,隐式地声明为内联函数,如果不希望是内联的,可以将成员的定义放在类外。

拷贝控制中的阻止拷贝。

1、阻止拷贝的原因:对于某些类来说,拷贝构造函数和拷贝赋值运算符没有意义。

2、阻止拷贝的方法有两个:新标准中可以将成员函数定义成删除的函数;在旧标准中可以使用private进行拷贝控制。推荐使用第一种。

3、删除的函数:对函数进行了声明,但是不能以任何方式使用它们,通过在函数参数列表后面加上=delete来将函数定义成删除的。=delete必须出现在函数第一次声明的地方。

4、析构函数是不能够删除的成员。因为把析构函数删除之后,就不能把定义的成员和对象删除了;但是可以使用指针动态分配这种类型的对象,不过不能释放指针资源。也就是说,对于析构函数已经删除的类型,不能定义该类型的对象或者不能释放指向该类型的动态分配对象的指针。

5、如果没有定义拷贝控制成员,对于某些类来说,编译器合成的拷贝控制成员也可能是删除的。如果一个类有数据成员不能够默认构造、拷贝、赋值或者销毁,那么对应的成员函数就是删除的。也就是类成员的性质会对其他成员函数造成影响。具体说来就是:

1)如果一个类的析构函数是删除的或者不可访问的,那么默认和拷贝构造函数是删除的,这样规定是为了防止创建对象,导致无法删除。

2)如果有引用类型或者const类型成员导致无法今次那个赋值操作,那么拷贝构造函数和拷贝赋值运算符就是删除的,因为需要赋值操作,而这两种类型不能被赋值。

除了类本身的因素之外,类成员如果是一个类类型。那么这个类类型成员的操作性质也会影响这个类的性质(例如类中有一个string类型成员,那么这个类的操作也受到string类的影响)

3)如果成员的拷贝赋值运算符是删除的,或者有引用或者const类型,那么类的合成拷贝赋值运算符定义为删除的。因为不能对这个成员进行赋值操作。

4)如果成员的析构函数是删除的,或者没有类内初始化器,那么类的默认构造函数是删除的,因为这个成员无法创建和无法销毁。

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:C++控制结构之——for循环
下一篇:{C++::CPLEX}C++常用方法{文件读写}

C语言创建windows窗口实例

C++回调函数是什么?

C++ shared_ptr和动态数组

C语言有哪些关键词,C语言44个关键词大全

  • 扫码领取资料

    回复关键字:视频资料

    免费领取 达内课程视频学习资料

  • 搜索抖音号

    搜索抖音号:1821685962

    免费领取达内课程视频学习资料

Copyright © 2021 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省