第十三章、拷贝控制

一、拷贝控制操作

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

class Foo{
public:Foo(const Foo&);        //拷贝构造函数;;最好是const类型;不应该是explicit的
}
  • 拷贝构造函数通常会被隐式使用,所以不应该是explicit
  • 如果我们没有为一个类定义拷贝构造函数,编译器会定义一个合成的拷贝构造函数
    • 合成的拷贝构造函数会将其非static成员简单的拷贝到正在创建的对象中
  • 拷贝初始化发生的情况
    • 用=定义变量时
    • 将一个对象作为实参传递给一个非引用类型的参数
      • 拷贝构造函数用来初始化非引用类类型参数,所以拷贝构造函数定义必须是引用类型
    • 从一个返回类型为非引用类型的函数返回一个对象
    • 用花括号列表初始化一个数组中的元素或一个聚合类中的成员

2、拷贝赋值运算符

  • 重载运算符本质上是函数,由operator关键字后接表示要定义的运算符的符号组成。
  • 运算符函数也要有一个返回类型和一个参数列表
  • 赋值运算符通常返回一个指向其左侧运算对象的引用
    Foo& operator = (const Foo&);
将右侧运算对象的每个非static成员赋予左侧运算对象的对应成员

3、移动构造函数

4、移动赋值运算符

5、析构函数:释放对象使用的资源,并销毁对象的非static数据成员

~Foo();
  • 没有返回值,不接受参数
  • 按成员初始化顺序的逆序销毁
  • 调用析构函数的情况:
    • 变量离开作用域时被销毁
    • 一个对象被销毁时,其成员被销毁
    • 容器被销毁时,其元素被销毁
    • 临时变量,当创建它的完整表达式结束时被销毁
  • 当指向一个对象的引用或指针离开作用域时,析构函数不会执行
  • 析构函数函数体本身不直接销毁成员;在之后的隐含的析构阶段中被销毁

6、三/五法则

  • 当我们决定一个类是否需要定义自己版本的拷贝控制成员时,基本原则是首先确定这个类是否需要一个析构函数
    • 合成析构函数不会delete一个指针数据成员;这个时候需要自己定义一个析构函数来释放构造函数分配的内存
    • 如果一个类需要自己定义的析构函数,则也需要自己定义的拷贝赋值运算符和拷贝构造函数
  • 需要拷贝构造函数也需要拷贝赋值运算;反之也是;但是不一定需要自己的析构函数

7、在函数的参数列表后加上=delete指出该函数为删除的

  • 析构函数不能是删除的:如果是删除的,则无法销毁此类型的对象了
  • 一个类有const成员,则它不能使用合成的拷贝赋值运算符:因为不能被赋值

二、拷贝控制和资源管理

1、通常管理类外资源的类必须定义拷贝控制成员;这种类需要通过析构函数来释放对象所分配的资源

2、当编写一个复制运算符时,一个好的模式是先将右侧运算对象拷贝到一个局部临时对象中。当拷贝完成后销毁左侧运算对象的现有成员就是安全的:防止自己赋值给自己

HasPtr& HasPtr::operator=(const HasPtr &rhs)
{auto newp = new string(*rhs.ps);delete ps;ps = newp;i = rhs.i;return *this;
}

三、对象移动

1、标准库容器、string和shared_ptr类既支持移动也支持拷贝。IO类和unique_ptr类可以移动但不能拷贝

2、右值引用:必须绑定到右值的引用;通过&&来获得右值引用

  • 右值引用只能绑定到一个将要被销毁的对象
  • 可以绑定到要求转换的表达式、字面常量或是返回右值的表达式,但不能直接绑定到一个左值上
    • 返回非引用类型的函数、连同算术、关系、位以及后置递增/减运算符都可以生成右值。可以把一个const的左值引用或一个右值引用绑定到这类表达式上
    • 返回左值的引用的函数,连同赋值、下标、解引用和前置递增/递减运算符,都是左值的表达式,可以把一个左值引用绑定到这类表达式上
  • 左值有持久的状态,右值要么是字面常量,要么是在表达式求值过程中创建的临时对象
    • 右值所引用的对象将要被销毁
    • 该对象没有其他用户
  • 变量是左值,因此不能将一个右值引用直接绑定到一个变量上,即使这个变量时右值引用类型也不行
int &&rr3 = std::move(rr1);
  • 调用move的标准库函数来获得一个绑定到左值上的右值引用
  • 调用move就意味着除了对rr1赋值或销毁它外,将不能再使用它
  • 使用move的代码应该使用std::move而不是move,这样可以避免潜在的名字冲突

3、移动构造函数和移动赋值运算符

StrVec::StrVec(StrVec &&s) noexcept     //第一个参数为类类型的引用;其他参数都必须有默认参数:elements(s.elements), first_free(s.first_free)    //使用noexcept来提示编译器不抛出异常
{s.elements = s.first_free = nullptr;    //确保移后源对象主语销毁无害的状态
}
如果一个类定义了自己的拷贝构造函数、拷贝赋值运算符或者析构函数,编译器就不会为它合成移动构造函数和移动赋值函数了; 只有当一个类没有定义任何自己版本的拷贝控制成员,且它的所有数据成员都能移动构造或移动赋值时,编译器才会为它合成移动构造函数或移动赋值运算符 定义了一个移动构造函数或移动赋值运算符的类必须也定义自己的拷贝操作,否则这些成员默认被定义为删除的 当一个类没有移动构造函数时,函数匹配规则保证该类型的对象会被拷贝,即使我们试图调用move来移动它们也是如此

4、右值引用和成员函数

  • 区分移动和拷贝的重载函数通常一个版本接收const T&;另一个版本接收&&;其他的const T&&和 T&不需要
void push_back(const &X);
void push_back(&&X);

5、在参数列表后面可以放置一个引用限定符

    • 对于&限定的函数,只能将它用作左值;对于&&限定的函数,只能用作右值
    • 一个函数可以同时使用const和引用限定,但是引用限定符必须跟在const限定符后面
    • 编译器会根据对象的左/右值属性来确定使用哪个版本的函数
    • 如果一个成员函数有引用限定符,则具有相同参数列表的所有版本都必须有引用限定符

转载于:https://www.cnblogs.com/dylqt/p/4880926.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419449.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ThreadLocal和线程同步机制的对比

ThreadLocal和线程同步都是为了解决多线程中相同变量的访问冲突问题,那么,二者的区别在哪里?和线程同步机制对比,ThreadLocal有什么优势? 同步机制中通过对象的锁机制保证同一时间只有一个线程来访问变量,这…

关于电脑自动获取和静态IP的问题

无法设置静态IP和设置了静态IP,但是无效的问题。 1、先是重新安装TCP/IP协议 选TCP/IP,点安装,再选择协议,点添加,选从磁盘安装,路径为:C:\Windows\inf\1394.inf,点打开 此时&#x…

javaweb中报404错误

这里只提供了一点建议,404大家都懂得是找不到请求的页面,一般就是URL路径请求错误 但是我最近发现自己出现这个错误的原因是:每次的struts的配置文件的命名空间忘记加在了form表单的action名字所对应的前面,一定不要忘了当自己定…

深入浅出: Java回调机制(异步)

一、什么是回调 回调,回调。要先有调用,才有调用者和被调用者之间的回调。所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。 回调…

WCF资料

Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4转载于:https://www.cnblogs.com/HQFZ/p/4884243.html

SSH中为什么action需要用多例而dao层和service层为什么就用单例就可以

很简单的道理,就跟你自来水一样,有很多的水龙头,但水管只有一个。为啥要很多水龙头,因为有多个人同时用;为了避免长队,只能这样来分担压力为啥只有一个水管,易维护,集中处理。 使用…

Nagios配置

其实上篇Nogios安装只是安装了Nagios基本组件,虽然能够打开主页,但是如果不配置相关配置文件文件,那么左边菜单很多页面都打不开,相当于只是一个空壳子。接下来,我们来学习研究一下Nagios的配置,了解一下基本的配置和了…

服务器启动时Webapp的web.xml中配置的加载顺序

一 1、启动一个WEB项目的时候&#xff0c;WEB容器会去读取它的配置文件web.xml&#xff0c;读取<listener>和<context-param>两个结点。 2、紧急着&#xff0c;容创建一个ServletContext&#xff08;servlet上下文&#xff09;&#xff0c;这个web项目的所有部分都…

JQuery.autocomplete扩展功能:实现多列自动提示

最近做一个项目&#xff0c;用到了JQuery的自动补全函数&#xff0c;但默认的是只显示一列数据&#xff0c;所以就略加修改&#xff0c;拿出来献丑了。 下面这个是默认调用本地数据&#xff1a; $("#tags").autocomplete(["c","java", &…

用java创建UDF,并用于Hive

典型代码如下&#xff1a; 导入UDF类&#xff1a; import org.apache.hadoop.hive.ql.exec.UDF; public class UpperCassUDF extends UDF{ public String evaluate(String input){ if(inputnull){ return null; } else{ return new String(input.toUpperCase()); } } } 导出jar…

单元素枚举类实现单例模式

本文转载自&#xff1a;点击打开链接 Inspired by Effective Java. Singleton模式是在编程实践中应用最广泛的几种设计模式之一。以前知道的&#xff0c;实现单例的方法有两种(下面的A、B)。刚刚在读《Effective Java的时候》学到一种新的更好的方法(E)&#xff1a;单元素的枚举…

java web开发之 spring单元测试

以前开发web项目从来不喜欢用单元测试&#xff0c;每次都需要启动服务器&#xff0c;在浏览器中调试&#xff0c;有些错误还不一定发现得到。 最近公司开发一个项目&#xff0c;任务繁重&#xff0c;不由觉得以前那种测试模式太笨拙了&#xff0c;于是学习了使用Junit&#xf…

对于SpringMVC框架使用的时候出现“警告: No mapping found for HTTP request with URI [/login]”的问题解决方案...

今天&#xff0c;在myeclipse上导入了前几天的一个项目&#xff0c;但是怎么都运行不起来&#xff0c;可是在别人的电脑上都可以。从早上一直调到了现在&#xff08;期间也看了好多关于此类的帖子&#xff0c;但是都没能解决我的问题&#xff09;&#xff0c;终于找到了解决方案…

MySQL数据库事务中的行级锁,表级锁,页级锁

锁定用于确保事务完整性和数据库一致性。 锁定可以防止用户读取其他用户正在更改的数据&#xff0c;并防止多个用户同时更改相同的数据。 如果不使用锁定&#xff0c;数据库中的数据可能在逻辑上变得不正确&#xff0c;而针对这些数据进行查询可能会产生想不到的结果。 在计算机…

#error

#define SIZE 250 #if SIZE<1 || SIZE>200 #error "SIZE must be between 1 and 200" #endif转载于:https://www.cnblogs.com/guxuanqing/p/4892802.html

搭建spring MVC项目

首先&#xff0c;是要放入spring mvc所需要的包&#xff1a; 如果不用json功能就不需要json和gson包,还有数据库驱动包&#xff0c;我这里是用的postgresql数据库&#xff0c;其他数据库需替换掉这个包 然后就是配置文件&#xff1a; 先是web.xml中需要加入以下内容&#xff…

换行的css属性

//正常换行word-break:keep-all;word-wrap:normal;//下面这行是自动换行word-break:break-all;word-wrap:break-word;word-wrap:normal | break-word; (内容换行)normal:默认的属性值.&#xff08;允许内容顶开指定的容器边界&#xff09;.break-word:内容将在边界内换行(不截断…

基于jquery.ajax的进一步封装

这是最近写项目用到的一个小功能&#xff0c;给大家分享下&#xff0c;希望对大家有帮助。 直接上代码&#xff1a; % page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8"%> <!DOCTYPE html PUBLIC &quo…

Serena Dimensions 介绍

Serena Dimensions是配置管理工具&#xff0c;基于进程的软件更改和配置管理解决方案。 官方网址&#xff1a;http://www.serena.com/index.php/en/products/application-development/dimensions-cm/overview/ eclipse与Dimensions的集成 转载于:https://www.cnblogs.com/seabi…

pigeon服务

点击打开链接