• C++编译器选择是否自动生成代码的背后逻辑


    C++编译器选择是否自动生成代码的背后逻辑

    编译器会为class和struct(实际上两者在C++中是一回事)自动生成构造函数、赋值操作符函数和析构函数。如果不是这样,那么开发者就必须自己写一些枯燥冗余的代码。然而编译器并不总是生成这些默认代码,当它觉得它无法生成正确的代码时,它就会拒绝生成默认代码。在以下几种情况中,编译器会认为它无法生成正确的代码:

    1. 当开发者自己定义了构造函数时

      编译器会认为开发者想要自己定义默认构造函数(即无参数的构造函数),它无法猜测开发者的想法,因此不会再自动生成默认构造函数。

    2. 当开发者自己定义了移动构造函数时

      编译器认为开发者可能希望仅使用移动语义而禁止拷贝,所以拷贝构造和拷贝赋值都不再自动生成。移动赋值也不会自动生成,而是交给开发者自己来定义,因为开发者已经在定义移动语义了。

    3. 当开发者自己定义了移动赋值操作函数时

      同上原因,拷贝构造和拷贝赋值不再默认生成。同样的原因,移动构造函数也不会自动生成。

    4. 当开发者自己定义了拷贝构造函数

      编译器认为开发者已经自己定义了拷贝语义,无法保证能自动生成正确的移动语义的代码,所以不再自动生成此类代码。C++11标准规定也不要自动生成拷贝赋值操作符函数代码,因为用户接管了拷贝语义的定义,但是Visual Studio仍然会生成拷贝赋值操作符函数代码。

    5. 当开发者自己定义了拷贝赋值操作函数时

      同上原因,不再生成移动语义的代码。C++11标准规定也不要自动生成拷贝构造函数代码,因为用户接管了拷贝语义的定义,但是Visual Studio仍然会生成拷贝构造函数代码。

    6. 当开发者自己定义了析构函数时

      移动构造和移动赋值都涉及到资源从源对象移动到目标对象,对于源对象来说是释放了对资源的所有权。而析构函数是释放资源,所以既然用户自己定义了用于释放资源目的的析构函数,那么说明移动的语义无法保持默认的实现,因此编译器不再自动生成移动语义的代码。

    7. 当开发者自己定义了虚析构函数时

      编译器不再自动生成默认析构函数代码。

  • 相关阅读:
    HTML5触屏版多线程渲染模板技术分享
    Yii2使用驼峰命名的形式访问控制器
    记一次MySQL中Waiting for table metadata lock问题的处理
    Mac下安装配置NMP环境
    Mac安装PHP(Homebrew/php弃用、其他第三方tap也已经弃用或者迁移后的安装配置方案)
    PHPStorm等编辑器debug调试(包括使用postman、soapUI)
    NoSQL数据库浅析
    PHP的抽象类和抽象方法以及接口总结
    Yii2中使用Soap WebSerivce
    Yii2之发送电子邮件
  • 原文地址:https://www.cnblogs.com/chengxin1985/p/16254192.html
Copyright © 2020-2023  润新知