拷贝构造函数

c++学习笔记

社会主义新天地 提交于 2020-03-30 21:50:51
1 函数 1.1 内联函数 inline bool isNumber ( char c ) { return ( c == '1' ); } int main ( int argc , _TCHAR * argv []) { //cout<<" Hello World! \n"; //printf("Hello World!"); if ( isNumber ( '1' )) printf ( "It is a Number" ); else printf ( "It isn't a Number" ); return 0; } 这种用 inline 定义的函数就是内联函数。 内联函数的出现是为了解决效率问题; 内联函数的函数体一般在 1 - 5 行之间; 内联函数内部不允许有控制语句,如果有控制语句,则它只会被当作一般的函数。 2 程序结构 2.1 外部存储类型 默认的函数声明或定义总是 extern 的; 带 extern 的是变量声明,不是变量实现; 2.2 静态函数 在 c++ 中所谓的静态函数和 c #中的是不同的,函数之所以声明为 static ,是为了和 extern 不同,就是让该函数只在这个文件内有效。 2.3 作用域 主要可以分为以下几种: l 局部作用域; void fn () { if ( int i == 5) //i 的作用域自此开始 i = 2* i

C++ 深拷贝和浅拷贝详解

我的梦境 提交于 2020-03-24 01:25:59
前言 在对象拷贝过程中,如果没有自定义 拷贝构造函数 ,系统会提供一个缺省的拷贝构造函数,缺省的拷贝构造函数对于基本类型的成员变量, 按字节复制 ,对于类类型成员变量,调用其相应类型的拷贝构造函数。 位拷贝(浅拷贝)举例,a指向b,b的改变其实会影响a的改变,同时a原本指向的空间发生泄漏。 然后这种情况下有了深拷贝。 何时调用? 以下情况都会调用拷贝构造函数: 一个对象以值传递的方式传入函数体 一个对象以值传递的方式从函数返回 一个对象需要通过另外一个对象进行初始化。 然后,我们现在从概念来理解一波 浅拷贝:位拷贝,拷贝构造函数,赋值重载 多个对象共用同一块资源,同一块资源释放多次,崩溃或者内存泄漏。 深拷贝:每个对象共同拥有自己的资源,必须显式提供拷贝构造函数和赋值运算符。 1 class String 2 { 3 4 public: 5 const char* c_str() 6 { 7 return _str; 8 } 9 10 String(const char* str = "") 11 :_str(new char[strlen(str) + 1]) 12 { 13 strcpy(_str, str); 14 } 15 String(const String &s) 16 :_str(NULL) 17 { 18 String tmp(s._str); 19 swap(

实验6:Problem F: 时间和日期类(IV)

≯℡__Kan透↙ 提交于 2020-03-19 13:59:05
Description 设计一个日期时间类,用于读取输入的数据,按格式输出日期和时间。 设计日期时间类DateTime由2个成员组成,分别是一个Date类对象和一个Time类对象; 设计DateTime类需支持以下操作: DateTime::DateTime()无参构造方法:初始化为1年1月1日、0时0分0秒; DateTime::DateTime(int,int,int,int,int,int)构造方法:依照参数(顺序为年月日、时分秒)初始化对象; 在上述两个DateTime类的构造函数中输出:“CREATE DateTime : (y, m, d, hh, mm, ss)”,其中y、m、d为初始化对象时的年月日值,h、m、s为初始化对象时的时分秒值。参见输出。 DateTime::DateTime(const Date&,const Time&)构造方法:依照参数传入的日期和时间初始化对象; 在这个DateTime类的构造函数中输出:“CREATE DateTime : (y, m, d) (hh, mm, ss)”,其中y、m、d为初始化对象时的年月日值,h、m、s为初始化对象时的时分秒值。参见输出。 DateTime:DateTime(const DateTime&)构造方法:拷贝构造函数,初始化对象。 在拷贝构造函数中输出:“COPY DateTime : (y, m,

拷贝、赋值与销毁

我只是一个虾纸丫 提交于 2020-03-15 12:21:09
一个类的拷贝控制操作包含: 拷贝构造函数 拷贝赋值运算符 移动构造函数 移动赋值运算符 析构函数 其中: 拷贝和移动构造函数定义了当用同类型的另一个对象初始化本对象时的操作。 拷贝和移动赋值运算符定义了将一个对象赋予同类型的另一个对象时的操作。 析构函数定义了当此类型对象销毁时的操作。 如果一个类没有定义所有这些拷贝控制成员,编译器会自动为它定义缺省的操作。对一些类来说,依赖于这些操作的默认定义会导致灾难。 拷贝构造函数 如果一个构造函数的第一个参数是自身类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数: class Foo{ public: Foo(); //默认构造函数 Foo(const Foo&); //拷贝构造函数 }; 拷贝构造函数的第一个参数必须是引用类型。 虽然可以定义一个接受非 const 引用的拷贝构造函数,但是此参数几乎总是 const 的。 拷贝构造函数在一些情况下会隐式使用,因此拷贝构造函数通常不定义成 explicit 。 合成拷贝构造函数 如果没有自定义拷贝构造函数,编译器会自动生成一个,与合成默认构造函数不同,即使定义了其他构造函数,编译器也会合成一个拷贝构造函数。 一般情况,合成的拷贝构造函数会从给定对象中依次将每个非 static 成员拷贝到正在创建的对象中,每个成员的类型决定了如何拷贝: 对类类型的成员

直接初始化、拷贝初始化

随声附和 提交于 2020-03-14 18:46:02
1.直接初始化 1)直接初始化实际上是要求编译器选择 参数最匹配 的一般构造函数 2.拷贝初始化 1)拷贝初始化实际上时要求编译器将 右侧运算对象 拷贝到正在创建的对象中, 如有需要,还要进行类型转换 2)拷贝初始化通常使用拷贝构造函数来完成 3)拷贝初始化发生时机: 用等号"=" 定义 变量时(注意定义二字,不是定义的时候使用等号是调用拷贝赋值运算符) 将一个对象作为实参传递给一个非引用的形参 从一个返回类型为非引用类型的函数中返回一个对象 用花括号列表初始化数组元素或者一个聚合类中的成员(因为也用到了等号"="定义变量) 3)编译器可以“绕过”拷贝构造函数:即编译器有时 可以 进行优化( 但不是必须 ),跳过拷贝构造函数,直接使用转换构造函数构造对象 string s = "666"; //先调用转换构造函数来构造一个临时的string对象(内容为:666),再调用拷贝构造函数用这个临时对象来构造s 编译器可以优化为: string s("666"); //直接调用转换构造函数来构造对象 来源: https://www.cnblogs.com/Joezzz/p/9717699.html

C++直接初始化,拷贝初始化,调用哪个构造函数?

浪子不回头ぞ 提交于 2020-03-09 09:46:30
很多C++新手不明白直接初始化、拷贝初始化,不清楚初始化过程中使用哪个构造函数。在学习过程中,要有基本概念,并且养成正确的认识也是非常重要的。因此整理了本文。 常见错误认识1: 1.使用()和使用=定义对象没什么区别。(直接初始化、拷贝初始化。) 2.直接初始化使用构造函数。(错,也可能使用拷贝构造函数。) 3.拷贝初始化使用拷贝构造函数。(错,也能使用构造函数。) 直接初始化 如果有一个新对象被定义(即创建了新对象),一定有构造函数被调用。 使用直接初始化时,我们实际上要求编译器使用普通的函数匹配,来提供参数最匹配的构造函数。因此直接初始化可能使用构造函数,也可能使用拷贝构造函数。 简单理解,用()来定义对象的就为直接初始化。 拷贝初始化 按字面意思理解即可,将一个对象给另一个对象初始化。 简单理解,用=定义对象的就为拷贝初始化。 注意: 拷贝赋值运算符也用在=的情况下,但是在对象已经创建并存在的情况下,只是修改对象的值而已。 而用=拷贝初始化是发生在定义一个对象的情况下,即对象此前尚未存在。 类定义如下: # include <string> # include <iostream> class Book { public : Book ( ) = default ; Book ( std :: string s ) : name ( s ) { std :: cout <<

c++中的右值引用的简单理解

纵然是瞬间 提交于 2020-02-26 22:00:09
以下的内容是我看了网上的博文后自己的总结,如果时间充裕的话,建议直接看 原文 。 简介:   c++中的右值引用十分不好理解,但是当你大概知道右值引用解决了c++中的什么问题后,会感觉右值引用还是很有用的。平时我们在c++中使用的引用为了和c++11引入的右值引用区分,一般把它称之为左值引用。左值引用很好理解,就是多个变量名绑定到了同一块内存上,操作这几个不同的变量名相当于操作同一块内存。但是右值引用就让人有点摸不着头脑了,一是右值(可以简单地认为就是字面常量或者临时变量)根本就没有变量名,这怎么引用?二是左值引用已经解决了按值传参的缺陷,右值引用又是干嘛的?正是由于这些问题让人感觉难以理解,我们需要分解问题,一步步去理解它。先复习一下什么是左值和右值。知道了左值右值的概念后,直接讲右值引用还是会感觉有点晦涩难懂,所以先引入一个move语义的概念,然后给出一个场景,再去看右值引用存在的意义。 左值和右值的区别:   区分左值和右值最简单的办法就是看一个内存空间是否可以使用&符号取得它的地址。能取到的就是左值,取不到的就是右值。比如    什么是move语义:   假设我们有一个这样的class:它里面包含着一个 int *m_memory 的成员变量,指向一块从堆上分配来的内存,并且假设这块内存有点大,复制一份这块内存中的字节需要一定的时间。  

C++学习笔记 第十九课 深拷贝

怎甘沉沦 提交于 2020-02-24 14:26:50
学习笔记内容来自:狄泰软件学院 唐佐林老师 的视频,十分感谢您的指导 特殊的构造函数 无参构造函数 当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且函数体为空 拷贝构造函数 当类中没有定义拷贝构造函数时,编译器默认提供一个拷贝构造函数,简单的进行成员变量的值复制 所以,下列定义的类并不是空的,因为有隐藏的默认提供的无参构造函数和拷贝构造函数 class Test{}; 初始化和赋值 在C++中,初始化和赋值不一样,初始化会触发构造函数,而赋值不会 拷贝构造函数 1.格式:claas_name(const class_name& another){} 2.意义:兼容C语言的初始化方式 拷贝构造函数中的深拷贝和浅拷贝 1.浅拷贝:拷贝后对象的物理状态相同 2.深拷贝:拷贝后对象的逻辑状态相同 PS:编译器提供的拷贝构造函数只进行浅拷贝 什么时候需要进行深拷贝 1.对象中有成员指代了系统中的资源 2.成员指向了动态内存空间 3.成员打开了外存中的文件 4.成员使用了系统中的端口 5… 示例程序: class Array { private : int * m_data ; int m_length ; public : Array ( ) { data = new int [ 5 ] ; } Array ( const Array & another ) { /* *

C++ 右值引用

蓝咒 提交于 2020-02-24 14:19:55
左值和右值 左值:当一个对象被用作左值的时候,用的是对象的身份(在内存中的位置)。 右值:当一个对象被用作右值的时候,用的是对象的值(内容)。 右值引用 重要性质:右值引用只能绑定到一个将要销毁的对象。因此,我们可以自由的将一个右值引用的资源移动到另一个对象中。 标准库move函数 move函数定义在头文件utility中,通过调用move函数可以获得绑定到左值上的右值引用。 int &&rr3 = std::move(rr1); move调用告诉编译器:我们有一个右值,但我们希望像一个右值一样处理它。意味着,除了对rr1赋值或销毁它外,我们将不再使用它的值。 注意:使用move应该使用std::move而不是move。这样可以避免潜在的名字冲突。 移动构造函数 类似拷贝构造函数,移动构造函数的第一个参数是该类类型的一个引用。不同于拷贝构造函数的是,这个引用参数在移动构造函数中是一个右值引用。与拷贝构造函数一样,任何额外的参数都必须有默认实参。 与拷贝构造函数不同,移动构造函数不分配任何新内存;它接管给定的对象中的内存。在接管内存之后,它将给定对象中的指针都置为nullptr。这样就完成了从给定对象的移动操作,此对象将继续存在。 移动赋值运算符 来源: https://www.cnblogs.com/xiaobaizzz/p/12356541.html

const成员-拷贝构造函数(copy constructor)

て烟熏妆下的殇ゞ 提交于 2020-02-18 22:19:30
const成员 const成员:被const修饰的成员变量、非静态成员函数 必须类里面初始化 class Car { public: const int m_price = 0; //const常量设置 Car() :m_price(0) {} //也可以在构造函数中初始化 void run() const { //const一般写最后 cout << "run()" << endl; m_price = 10; } }; const成员函数 两个同名函数构成了重载 void run() const {} void run() {} 引用类型成员变量必须初始化 int age; int & m_price = age; car(int &price) :m_price(price) {} 拷贝构造函数(copy constructor) 拷贝构造函数是构造函数的一种 当利用已存在的对象创建一个新对象时(类似于拷贝),就会调用新对象的拷贝构造函数进行初始化 //拷贝构造函数 Car(const Car &car) { cout << "Car(const Car &car)" << endl; } Car car4(car3); 来源: https://www.cnblogs.com/sec875/p/12328947.html