首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一文入魂:妈妈再也不用担心我不懂C++移动语义了!

(二)默认情况下,我们拥有一切 我们知道,在C++11之前,如果我们定义一个空类,编译器会自动为我们生成构造函数、析构函数、拷贝构造函数以及拷贝赋值运算符。该特性在移动语义上得以延伸。...,执行编译器默认生成的构造函数MyClass B{ A }; // OK,执行编译器默认生成的拷贝构造函数MyClass C{ std::move(A) }; // OK,执行编译器默认生成的移动构造函数...五、使用移动语义时需要注意的其他内容 在最后一节,我们聊聊与移动语义相关的一些额外内容。...因此,编译器会启用NRVO,直接让myClass对象使用对象A。这样一来,在整个过程中,我们只有一次创建对象A时构造函数的调用开销,省去了拷贝构造函数以及析构函数的调用开销: 为NRVO点赞!...因此,当返回局部对象时,我们不用画蛇添足,直接返回对象即可,编译器会优先使用最佳的NRVO,在没有NRVO的情况下,会尝试执行移动构造函数,最后才是开销最大的拷贝构造函数。

1.3K20

Google C++ 编程风格指南(三):类

若未声明构造函数, 则编译器会生成一个默认的构造函数, 这有可能导致某些成员未被初始化或被初始化为不恰当的值. 定义: new 一个不带参数的类对象时, 会调用这个类的默认构造函数....这么做的原因是: 如果你没有提供其它构造函数, 又没有定义默认构造函数, 编译器将为你自动生成一个. 编译器生成的构造函数并不会对对象进行合理的初始化....对于用户定义的类型, 移动操作一般是通过移动构造函数和移动赋值操作符实现的. 拷贝 / 移动构造函数在某些情况下会被编译器隐式调用. 例如, 通过传值的方式传递对象....如果某区段没内容, 可以不声明....译者 (YuleFox) 笔记 不在构造函数中做太多逻辑相关的初始化; 编译器提供的默认构造函数不会对变量进行初始化, 如果定义了其他构造函数, 编译器不再提供, 需要编码者自行提供默认构造函数; 为避免隐式转换

83240
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    《C++Primer》第十五章 面向对象程序设计

    必须要搞清楚的是,动态绑定只有当我们通过指针或者调用虚函数时才会发生,也只有在这种情况下对象的动态类型才能可能与静态类型不同。 2....只有当一个类没有定义任何自己版本的拷贝控制成员,且类的每个static数据成员都可以移动时,编译器才会为它合成移动构造函数或者移动赋值运算符。 3....在实际编程中,如果基类中没有默认、拷贝或移动构造函数,那么一般情况下派生类也不会定义相应的操作。 5....移动操作与继承 前面提到,大多数基类都会定义一个虚析构函数,因此在默认情况下基类通常不包含合成的移动操作,而且在派生类中也没有合成的移动操作。...类不能继承默认、拷贝和移动构造函数。如果派生类没有直接定义这些构造函数,则编译器将为派生类合成它们。

    1.2K20

    如何设计一个C++的类?

    类需要自己写构造函数和析构函数吗? 反正我每次定义一个类的时候都会明确把构造函数和析构函数写出来,即便它是空实现,即便我不写编译器也会视情况默认生成一个,自动生成的称为默认构造函数。...但我不想依赖编译器,也建议大家不要过度依赖编译器,明确写出来构造函数和析构函数也是一个好习惯,多数情况下类没有那么简单,多数情况下编译器默认生成的构造函数和析构函数不一定是我们想要的。...tips:编译器在某些情况下会生成移动构造函数或移动赋值运算符,但记住这些情况太麻烦了,建议手动控制,明确要的时候就自己写一个,明确不要的时候就delete掉。...什么是默认构造函数?看下百度百科的定义: 默认构造函数(default constructor)就是在没有显式提供初始化式时调用的构造函数。...如果你期望在某个成员函数内不更改成员函数,而又没有标记为const,这时自己或者其他人在此函数内改动了某些成员变量,编译器对此没有任何提示,这就有可能产生潜在的bug。

    1.6K20

    C++相关基础知识总结笔记

    struct 默认权限为 public , class 默认权限为 private 类的构造相关 默认情况下,c++编译器至少为我们写的类增加3个函数 : 1.默认构造函数(无参,函数体为空) 2.默认析构函数...如果派生类的构造函数没有显式调用基类的构造函数,那么编译器会自动调用基类的默认构造函数(如果有的话)。...如果基类没有默认构造函数,或者需要传递参数给基类构造函数,可以在派生类的构造函数初始化列表中显式调用基类的构造函数。 构造函数的规则 如果类中定义了任何构造函数,编译器就不会自动生成默认构造函数。...如果类中定义了拷贝构造函数或移动构造函数,编译器就不会自动生成相应的默认构造函数。...如果类中定义了任何构造函数,但没有定义拷贝构造函数或移动构造函数,编译器会自动生成默认的拷贝构造函数和移动构造函数。 构造函数的应用场景 初始化成员变量:确保对象在使用前处于有效状态。

    21330

    C++11『右值引用 ‖ 完美转发 ‖ 新增类功能 ‖ 可变参数模板』

    ,类中共有八个天选之子(编译器会默认生成) 天选之子 的意思就是 即使我们不写,编译器也会默认生成(有条件) 之前六个 天选之子 的生成规则这里就不再阐述了,主要来说说 移动语义 相关的两个函数 移动语义就是通过右值引用将资源转移再利用...,对于自定义类型,会去调用它的 移动构造 函数,如果没有,就调用 拷贝构造(目的:涉及深拷贝的类编译器期望我们自己设计 移动构造 函数) 移动赋值 的生成逻辑与上面一致 编译器为什么会这么要求?...核心在于 与临界资源(将亡值)交换资源 默认生成的 移动构造 或者 移动赋值 并非没有用,就像 拷贝构造 一样,默认生成的拷贝构造会去调用该函数中涉及类的 拷贝构造,也就是说,只要底层类没问题,自动生成的函数也可以实现...在想让编译器生成的函数之后加上 default 关键字,如果类中涉及 动态内存管理(比如这里的 string),是不推荐使用默认生成函数的,因为会涉及到 深拷贝 并且由于 移动构造 属于 构造 家族,移动赋值...移动构造 这里想强调的是 default 可以指定编译器自动生成类中的默认成员函数 能否使用 default 生成除默认成员函数之外的其他成员函数?

    54650

    3.类和对象(中)

    类的默认成员函数 默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数(就是我们不写,编译器会默认生成一份)。...一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重要,我们稍微了解一下即可。...有三个默认构造函数:无 参构造函数、全缺省构造函数、我们不写构造时编译器默认生成的构造函数,都叫做默认构造函数。但是 这三个函数有且只有一个存在,不能同时存在。...要注意很多同学会认为默认构造函数是编译器默认生成那个叫默认构造,实际上无参构造函数、全缺省构造函数也是默认构造,总结一下就是不传实参就可以调用的构造都叫默认构造。 7....我们不写,编译器默认生成的构造,对内置类型成员变量的初始化没有要求,也就是说是是否初始化是不确定的,看编译器。对于自定义类型成员变量,要求调用这个成员变量的默认构造函数初始化。

    7310

    【C++】C++11新特性——右值引用,来看看怎么个事儿

    _capacity; } //移动构造 string(string&& str) { swap(str); } 虽然即使没有移动构造,只有上面的拷贝构造也能因为有const修饰而接收左值和右值,但是有了移动构造编译器会走最匹配的...返回局部的大对象,调用移动构造的代价非常低,很实用。 也不是说所有的局部对象传值返回都要走移动构造,只有需要深拷贝的对象移动构造才有意义,像日期类这种对象拷贝构造和移动构造没有区别。...三、类的新功能 3.1 新默认成员函数 前面我们学了类的6个默认成员函数: 构造函数 析构函数 拷贝构造函数 拷贝赋值重载 取地址重载 const 取地址重载 默认成员函数是我们不写编译器会默认生成的函数...它们两个的特点是: 如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。...默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝(值拷贝),自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造 移动赋值重载和移动构造基本类似

    14110

    详细c++必修:类和对象(二)

    ⼀个类,我 们不写的情况下编译器会默认⽣成以下6个默认成员函数 其中前四个用的比较频繁,我们一定要做到熟练使用。 C++11以后还会增加两个默认成员函数,移动构造和移动赋值。我们不做讲解。...其中不写自动生成的看编译器,有可能初始化为0,也有能是随机值(上图编译环境是vs2022,是随机值) ⽆参构造函数、全缺省构造函数、我们不写构造时编译器默认⽣成的构造函数,都叫做默认构造函...比特就业课 ⽆参构造函数、全缺省构造函数、我们不写构造时编译器默认⽣成的构造函数,都叫做默认构造函 数。但是这三个函数有且只有⼀个存在,不能同时存在。...我们不写,编译器默认⽣成的构造,对内置类型成员变量的初始化没有要求,也就是说是是否初始 化是不确定的,看编译器。对于⾃定义类型成员变量,要求调⽤这个成员变量的默认构造函数初始 化。...我们在主函数中调用。其中Stack类中有指针指向的空间,所以必须写析构,但是MyQueue类中却不用写。 这是为什么? 因为编译器默认⽣成MyQueue的析构函数调⽤了Stack的析构。

    13210

    C++中空类:认识它的6个默认函数和6个构造函数

    空类介绍在C++中,一个不包含任何数据成员、成员函数(包括虚函数)和基类的类被称为空类。尽管空类看起来没有任何用途,但在某些情况下,它们可以作为一种类型安全的标记或标识符使用。...例如,我们可以定义一个空类,然后使用它来创建一个特殊的函数重载,这个重载只有在给定一个空类对象时才会被调用。...C++中空类的6个默认函数默认构造函数:当一个对象被创建但没有被赋予初始值时,会调用默认构造函数。...当我们没有为类定义任何构造函数时,C++会提供一个默认的构造函数,它不接受任何参数,也不执行任何操作。但是,它的存在确保了我们可以创建类的对象。...当我们需要复制一个对象时,拷贝构造函数就会被调用。如果我们没有定义拷贝构造函数,C++会提供一个默认的拷贝构造函数,它会逐个复制对象的所有成员。

    7200

    C ++ 中不容忽视的 25 个 API 错误设计!

    因此,如果你的类只包含简单的数据类型,并且你计划使用隐式生成的移动构造函数,那么如果你定义复制构造函数则不可能。在这种情况下时,你必须显式定义移动构造函数。...为什么这是一个错误? 如果该构造函数不破坏其强大的异常安全保证,则STL容器只能在其调整大小操作中使用移动构造函数。...将API标记为noexcept有多种分歧,包括某些编译器优化,例如移动构造函数的优化。...错误#6:不将单个参数构造函数标记为显式 为什么这是一个API设计错误? 允许编译器进行一次隐式转换以将参数解析为函数。...这意味着编译器可以使用可用* single argument*调用的构造函数将一种类型转换为另一种类型,以获得正确的参数类型。

    1.6K20

    2020最全Java面试题--基础篇

    11.假设我们在不传递任何参数的情况下运行Java类。 Main方法中参数的String数组的值是什么? 默认情况下,Java中参数的String数组的值为空。...构造函数是一个特殊的函数,具有与类名相同的名称。 没有构造函数,就没有其他方法可以创建对象。 默认情况下,Java为每个对象提供默认的构造函数。...如果我们重载了一个构造函数,那么必须实现这个默认的构造函数。 5. 为什么Java类中需要默认构造器? 如果没有定义其他构造函数,则默认构造函数是Java会自动生成的无参构造函数。...根据Java规范,如果类中没有重载的构造函数,它将提供一个默认的构造函数。但这并没有说明在类中编写重载构造函数的情况。 我们至少需要一个构造函数来创建一个对象,这就是Java提供默认构造函数的原因。...Java中的默认构造器返回的值是什么? 当我们用Java调用构造函数时,它返回由它创建的对象。 这就是我们用Java创建新对象的方式。 7. 我们能继承构造函数吗?

    58431

    现代C++之容器

    不建议在接口中使用const string&,除非确知调用者已经持有 string:如果函数里不对字符串做复杂处理的话,使用 const char* 可以避免在调用者只有 C 字符串时编译器自动构造 string...如果需要改变调用者的字符串内容,使用 string& 作为参数类型(通常不推荐)。...2.vector 2.1 异常安全性 vector 通常保证强异常安全性,如果元素类型没有提供一个保证不抛异常的移动构造函数,vector 通常会使用拷贝构造函数。...因为 stack(queue)为保证强异常安全性,如果元素类型没有提供一个保证不抛异常的移动构造函数, 通常会使用拷贝构造函数。...pop作用是释放元素,c++98设计时还没有移动构造的概念,所以如果返回成员,必须要调用拷贝构造函数,这时分配空间可能出错,导致构造失败,要抛出异常,所以没必要返回成员。

    1K10

    【Modern C++】深入理解移动语义

    如果开发人员没有显示定义移动构造函数和移动赋值运算符,那么编译器也会生成默认。...与其他四个特殊成员函数不同,编译器生成默认的移动构造函数和移动赋值运算符需要,满足以下条件: 如果一个类定义了自己的拷贝构造函数,拷贝赋值运算符或者析构函数(这三者之一,表示程序员要自己处理对象的复制或释放问题...),编译器就不会为它生成默认的移动构造函数或者移动赋值运算符,这样做的目的是防止编译器生成的默认移动构造函数或者移动赋值运算符不是开发人员想要的 如果类中没有提供移动构造函数和移动赋值运算符,且编译器不会生成默认的...,那么我们在代码中通过std::move()调用的移动构造或者移动赋值的行为将被转换为调用拷贝构造或者赋值运算符 只有一个类没有显示定义拷贝构造函数、赋值运算符以及析构函数,且类的每个非静态成员都可以移动时...,编译器才会生成默认的移动构造函数或者移动赋值运算符 如果显式声明了移动构造函数或移动赋值运算符,则拷贝构造函数和拷贝赋值运算符将被 隐式删除(因此程开发人员必须在需要时实现拷贝构造函数和拷贝赋值运算符

    88110

    【C++】揭秘类与对象的内在机制(核心卷之构造函数与析构函数的奥秘)

    Init函数,然后调用它给对象初始化,但是如果我们有默认构造函数,那么在创建对象时就会自动进行调用,非常方便    ⼀个类,我们不写的情况下编译器会默认⽣成以下6个默认成员函数,需要注意的是这6个中最重要的是前...自定义类型:当我们不写构造函数时,编译器会默认⽣成一个构造函数,虽然我们看不到,但是编译器确实会进行生成,这个构造对内置类型成员变量的初始化没有要求,比如int、double等类型,这个默认生成的构造函数对它们进行初始化时没有要求...既然我这么提问了,那么答案很明显就是不能了,为了讲明白这件事,我们接下来引入默认构造和非默认构造函数的概念,只有默认构造函数才能在对象实例化时自动进行调用 默认构造函数有三种,即没有写构造函数时编译器默认生成的构造函数...,很明显不属于那三种默认构造函数,如果对象实例化时编译器去自动调用这个构造函数,就会发现三个形参没有值可以用,一定会报错,所以C++就规定了只有上面那三种默认构造可以对构造函数进行自动调用    ...只有默认构造函数可以在对象初始化时自动调用,⽆参构造函数、全缺省构造函数、我们不写构造时编译器默认⽣成的构造函数,这三种构造函数都叫做默认构造函数,但是这三个函数有且只有⼀个存在,不能同时存在

    7210

    【C++】构造函数和析构函数

    一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重要,我们稍微了解一下即可。...第二:编译器默认生成的函数不满足我们的需求,我们需要自己实现,那么如何自己实现? 在本篇文章,主要讲构造函数和析构函数,其他成员函数,放到其他文章讲。 2....无参构造函数、全缺省构造函数、我们不写构造时编译器默认生成的构造函数,都叫做默认构造函数。但是这三个函数有且只有一个存在,不能同时存在。...要注意很多同学会认为默认构造函数是编译器默认生成那个叫默认构造,实际上无参构造函数、全缺省构造函数也是默认构造,总结一下就是不传实参就可以调用的构造就叫默认构造。...我们不写,编译器默认生成的构造,对内置类型成员变量的初始化没有要求,也就是说是是否初始化是不确定的,看编译器。对于自定义类型成员变量,要求调用这个成员变量的默认构造函数初始化。

    12210

    认真理一理C++的构造函数

    默认构造函数 如果没有定义任何构造函数,编译器会为我们提供无参的默认构造函数。但是有例外 如果定义了自己的构造函数,编译器也不会提供默认构造函数。...如果类中某个成员它自己没有默认构造函数(无参构造函数),那么编译器也就不能合成默认构造函数。...,但是没有无参构造函数;一个Test,没有定义构造函数,准备让编译器生成默认的。...,这会被编译器认为是一个函数的声明,因此要用下面的方式: Test test; 禁止拷贝形式的初始化 在没有其他限制的情况下,对于只有一个实参的构造函数而言,可以使用拷贝形式的初始化,即在初始化test...总结 关于构造函数的内容还有很多,在介绍继承,多态,拷贝,移动等内容后再展开,本文总结如下: 构造函数没有返回值 构造函数名与类名相同 构造函数可以重载 构造函数不能被声明成const 对于只有一个实参的构造函数而言

    56220

    【C++学习篇】C++11第三期

    没有⾃⼰实现移动构造函数,且没有实现析构函数 、拷⻉构造、拷⻉赋值重载中的任意⼀个。那么编译器会⾃动⽣成⼀个默认移动构造。...默认⽣成的移动构造函数,对于内置类型成员会执 ⾏逐成员按字节拷⻉,⾃定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调⽤移动构造,没有实现就调⽤拷⻉构造。 2....如果你没有⾃⼰实现移动赋值重载函数,且没有实现析构函数 、拷⻉构造、拷⻉赋值重载中的任意⼀个,那么编译器会⾃动⽣成⼀个默认移动赋值。...在C++11中更简单,只需在该函数声明加上=delete即可,该语法指⽰编译器不⽣成对应函数的默认版本,称=delete修饰的函数为删除函数。(=delete就是不允许拷贝) 2....包装器 2.1 function 示例1: 示例2:包装其他类域里面的函数 2.1.1 为什么调用类域里面的静态函数不需要定义对象? 2.1.2 我们来回忆一下,函数指针调用的方式!!!

    4510

    第 13 章 拷贝控制

    当一个类没有定义这些拷贝控制成员时,编译器会自动地定义缺失的操作,但编译器定义的版本的行为可能并非我们所想。 拷贝构造函数,第一个参数是自身类类型的引用,且任何额外参数都有默认值的构造函数。...如果类的某个成员的析构函数是删除或不可访问的,或是类有一个没有类内初始化器的引用成员,或是类有一个没有类内初始化器且无法默认构造的 const成员,则该类的默认构造函数被定义为删除的。...移动构造函数,第一个参数是该类类型的一个右值引用,而其他额外参数都必须有默认实参。移动构造函数不分配任何新内存,接管对象的内存。...不抛出异常的移动构造函数和移动赋值运算符的声明和定义处都必须指定 noexcept。 移动赋值运算符也必须检查自赋值情况,因为此右值可能是 move调用自身返回的结果。...只有当一个类没有定义任何自己版本的拷贝控制成员,且它的所有非 static数据成员都能移动构造或移动赋值时,编译器才会为它合成移动构造函数或移动赋值运算符。

    1K50
    领券