拷贝构造函数

[译]详解C++右值引用

拈花ヽ惹草 提交于 2019-12-09 14:33:49
C++0x标准出来很长时间了,引入了很多牛逼的特性 [1] 。其中一个便是右值引用,Thomas Becker的文章 [2] 很全面的介绍了这个特性,读后有如醍醐灌顶,翻译在此以便深入理解。 目录 概述 move语义 右值引用 强制move语义 右值引用是右值吗? move语义与编译器优化 完美转发:问题 完美转发:解决方案 Rvalue References And Exceptions The Case of the Implicit Move Acknowledgments and Further Reading 概述 右值引用是由C++0x标准引入c++的一个令人难以捉摸的特性。我曾偶尔听到过有c++领域的大牛这么说: 每次我想抓住右值引用的时候,它总能从我手里跑掉。 想把右值引用装进脑袋实在太难了。 我不得不教别人右值引用,这太可怕了。 右值引用恶心的地方在于,当你看到它的时候根本不知道它的存在有什么意义,它是用来解决什么问题的。所以我不会马上介绍什么是右值引用。更好的方式是从它将解决的问题入手,然后讲述右值引用是如何解决这些问题的。这样,右值引用的定义才会看起来合理和自然。 右值引用至少解决了这两个问题: 实现move语义 完美转发(Perfect forwarding) 如果你不懂这两个问题,别担心,后面会详细地介绍。我们会从move语义开始

C++ 类(构造函数和析构函数)

≡放荡痞女 提交于 2019-12-07 08:25:58
文章概述 构造函数和析构函数的由来? 构造函数和析构函数的基本语法 C++编译器构造析构方案 PK 对象显示初始化方案 构造函数的分类以及调用 默认的构造函数 构造函数调用规则 构造函数和析构函数的总结 构造函数和析构函数的由来 类的数据成员不能在类的声明时候初始化,为了解决这个问题? 使用构造函数处理对对象的初始化。构造函数是一种特殊的成员函数,与其他函数不同,不需要用户调用它,而是创建对象的时候自动调用。析构函数是对象不再使用的时候,需要清理资源的时候调用。 构造函数和析构函数的基本语法 a. 构造函数: C++中的类需要定义与类名相同的特殊成员函数时,这种与类名相同的成员函数叫做构造函数; 构造函数可以在定义的时候有参数; 构造函数没有任何返回类型。 构造函数的调用: 一般情况下,C++编译器会自动的调用构造函数。特殊情况下,需要手工的调用构造函数。 class Test { public : //构造函数 Test() { } } b. 析构函数: C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的函数是析构函数; 析构函数没有参数和没有任何返回类型; 析构函数在对象销毁的时候自动调用; 析构函数调用机制: C++编译器自动调用。 class Test { ~ Test () { } } C++编译器构造析构方案 PK 对象显示初始化方案 class Test {

C/C++——构造函数和析构函数

こ雲淡風輕ζ 提交于 2019-12-07 07:36:47
本文对类的构造函数和析构函数进行总结,主要包括了构造函数的初始化、重载、使用参数和默认参数,拷贝构造函数和析构函数,希望能帮助读者在程序开发中更好的理解类,属 于 C/C++ 基础。 1、 构造函数 构造函数与类名相同,它是一种特殊的成员函数,没有返回值类型和返回值。在对象建立时自动调用,不需要也不能由用户调用。构造函数主要为对象开辟内存空间,完成对象数据成员的初始化。 (1) 、构造函数的初始化 构造函数的主要功能是给对象初始化,初始化有两种方式,一种是用参数初始化列表,这种方式简练;另一种是在构造函数的函数体内对数据成员进行赋值实现初始化,这种方式方便直观。 参数初始化列表初始化 参数初始化列表初始化的形式是在函数的首部的末尾加冒号,然后列出用逗号分隔的数据成员列表初始化表。如: T ::T( int a , int b ) :hour( a ),minute( b ) {} 表示用a初始化hour,用b初始化minute,即 hour=a; minute=b; 虽然后面的花括号是空的,但已经给对象进行了初始化。 注意: ① 对于 const 或引用类型的成员必须在构造函数初始化列表中进行初始化,这是初始化它们的唯一机会, 原因分析在赋值语句初始化段。 ② 不能用参数初始化列表对静态数据成员初始化,而且只能在类外初始化 ,可以像普通数据成员那样通过对象访问,也可以通过类名访问

类和对象(中)C++

本小妞迷上赌 提交于 2019-12-05 01:14:02
类中哪些默认的事儿…… 1. 类的6个默认成员函数: 如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情 况下,都会自动生成下面6个默认成员函数。 class Date{}; 2. 构造函数: 构造函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员 都有 一个合适的初始值,并且在对象的生命周期内只调用一次。 构造函数的给出方式如下,参数可以给出缺省值,也可以重载构造函数。 class Date { public: Date(int year = 2000,int month=1,int day=1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; }; int main() { Date d1; return 0; } 构造函数是特殊的成员函数,需要注意的是,构造函数的虽然名称叫构造,但是需要注意的是构造函数的主 要任务并不是开空间创建对象,而是初始化对象。 其特征如下: 1、 函数名与类名相同。 2、无返回值。 3、对象实例化时编译器自动调用对应的构造函数。 4、构造函数可以重载。 5、如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定

对象克隆

牧云@^-^@ 提交于 2019-12-04 15:44:52
在C++中,有一个特殊的构造函数叫做拷贝构造函数,用于解决对象间浅层拷贝存在的问题。 C++中每一个类会有一个默认的拷贝构造函数,使用默认的拷贝构造函数实现的是对象的浅层拷贝,大致的工作就是将一个对象的“ 成员属性 ”值逐一复制到另外一个对象。默认的拷贝构造函数能够满足大多数的使用需求,但如果类的成员属性中含有指针变量,使用默认的拷贝构造函数就会出现 “指针悬挂” 的问题。 什么是指针悬挂?简单的说是这么个情况:某个类A的成员属性中含有指针变量p,通过默认的拷贝构造函数由对象a1创建一个对象a2,由于默认的拷贝构造函数实现的是数值的简单复制,所以最终对象a1和a2的指针变量将具有相同的数值,即指向相同的内存空间,如果某个对象将这个空间释放,另一个对象并不知情,继续使用这个空间...... Java中没有指针变量,也存在类似的问题。 来源: https://www.cnblogs.com/KenBaiCaiDeMiao/p/11872002.html

C++中的深拷贝和浅拷贝 QT中的深拷贝,浅拷贝和隐式共享

别说谁变了你拦得住时间么 提交于 2019-12-04 14:34:58
下面是C++中定义的深,浅拷贝 当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数: (1)一个对象以值传递的方式传入函数体 (2)一个对象以值传递的方式从函数返回 (3)一个对象需要通过另外一个对象进行初始化。 如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝,后面将进行说明。 自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。 浅拷贝和深拷贝   在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。   深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。下面举个深拷贝的例子。 总结:有资源的重新分配:深拷贝;无:浅拷贝(直接的调用默认的构造函数实际上也是共享了一款数据的内存

Java中如何克隆集合——ArrayList和HashSet深拷贝

牧云@^-^@ 提交于 2019-12-03 21:49:27
编程人员经常误用各个集合类提供的拷贝构造函数作为克隆List,Set,ArrayList,HashSet或者其他集合实现的方法。需要记住的是,Java集合的拷贝构造函数只提供浅拷贝而不是深拷贝,这意味着存储在原始List和克隆List中的对象是相同的,指向Java堆内存中相同的位置。增加了这个误解的原因之一是对于 不可变对象 集合的浅克隆。由于不可变性,即使两个集合指向相同的对象是可以的。字符串池包含的字符串就是这种情况,更改一个不会影响到另一个。使用ArrayList的拷贝构造函数创建雇员List的拷贝时就会出现问题,Employee类不是不可变的。在这种情况下,如果原始集合修改了雇员信息,这个变化也将反映到克隆集合。同样如果克隆集合雇员信息发生变化,原始集合也会被更改。绝大多数情况下,这种变化不是我们所希望的,克隆对象应该与原始对象独立。解决这个问题的方法是 深克隆集合 ,深克隆将递归克隆对象直到基本数据类型或者不可变类。本文将了解一下深拷贝ArrayList或者HashSet等集合类的一种方法。如果你了解 深拷贝与浅拷贝之间的区别 ,那么理解集合深克隆的方法就会很简单。 Java集合的深克隆 下面例子有一个Employee集合,Employee是可变对象,成员变量name和designation。它们存储在HashSet中。使用java.util

阻止编译器默认生成拷贝构造函数和拷贝赋值函数

匿名 (未验证) 提交于 2019-12-03 00:36:02
为了阻止编译器默认生成拷贝构造函数和拷贝赋值函数,我们需要手动去重写这两个函数,某些情况 下,为了避免调用拷贝构造函数和 拷贝赋值函数,我们需要将他们设置成private,防止被调用。 但是类的成员函数和friend函数还是可以调用private函数,如果这个private函数只申明不定义,则会产生一个连接错误; 针对上述两种情况,我们可以定一个base类, 在base类中将拷贝构造函数和拷贝赋值函数设置成private ,那么派生类中编译器将不会自动生成这两个函数,且由于base类中该函数是私有的,因此,派生类将阻止编译器执行相关的操作。 另一个例子,如果在base类中,我们把赋值构造函数定义为私有成员。派生类的赋值会怎么样呢? 这时,如果我们没有定义赋值构造函数,则C++会拒绝为其派生类生成一个拷贝赋值操作符这些赋值操作。 因为在赋值时,会让基类成员调用基类自己的赋值构造函数,但是这时是私有的,所以就会出问题。 [cpp] view plain copy "font-size:14px;" > class protected private const const class public 我们希望最后这两句话不能通过编译,那么怎样在C++中实现呢?一种想当然的做法,就是不去写拷贝构造函数和赋值运算符。但由上一个条款可以知道,这样做是行不通的,C+

拷贝控制

匿名 (未验证) 提交于 2019-12-02 23:56:01
1. 拷贝构造函数    如果一个构造函数的 第一个参数是自身类型的引用 ,且额外参数都有默认值,则此构造函数是拷贝构造函数。    而合成拷贝构造函数是缺省的拷贝构造函数,即默认的拷贝构造函数,一般情况下,它的实际操作是 对所有成员变量进行一次赋值操作 。 如果成员的缺省的赋值操作不能满足需求(如是一个链表或含有指针) ,就必须要对成员类定义重载赋值操作符,才能够让合成拷贝构造函数起作用。    通常 在函数的调用时,使用非引用的对象类型作函数参数时,这个时候会调用该类的拷贝构造函数 ,如下形式: #include <string> #include <string.h> #include <stdlib.h> #include <iostream> using namespace std ; class Book { private : char * _bookISBN ; float _price ; public : Book ( char * ISBN , float price = 0.0f ): _price ( price ){ _bookISBN = ( char *) malloc ( strlen ( ISBN ) + 1 ); strcpy ( _bookISBN , ISBN ); cout << "构造函数被调用." << endl ; } Book (

拷贝构造函数调用的时机

匿名 (未验证) 提交于 2019-12-02 23:39:01
链接: https://www.nowcoder.com/questionTerminal/a0f69e79a60d45f2b441c7e92f8f6ad3 来源:牛客网 拷贝构造函数调用的时机: 1、当用类的一个对象初始化该类的另一个对象时 4、需要产生一个临时类对象时 文章来源: https://blog.csdn.net/weixin_37864269/article/details/91398872