C++ 什么是C++;?

C++ 什么是C++;?,c++,constructor,C++,Constructor,我在读这个 它提到了普通默认构造函数、普通复制构造函数、复制赋值操作符、普通析构函数。什么是平凡的,什么不是平凡的?如果以下所有条件都成立,则类A的构造函数是: 它是隐式定义的(编译器合成) 没有虚拟函数和虚拟基类 A的所有直接基类都有平凡的构造函数 的所有非静态数据成员的类都有平凡的构造函数 简单地说,“普通”特殊成员函数字面上是指以非常简单的方式完成其工作的成员函数。对于不同类型的特殊成员函数,“直截了当的方式”意味着不同的事情 对于默认的构造函数和析构函数,“微不足道”的字面意思是“什么

我在读这个


它提到了普通默认构造函数、普通复制构造函数、复制赋值操作符、普通析构函数。什么是平凡的,什么不是平凡的?

如果以下所有条件都成立,则类A的构造函数是:

  • 它是隐式定义的(编译器合成)
  • 没有虚拟函数和虚拟基类
  • A的所有直接基类都有平凡的构造函数
  • 的所有非静态数据成员的类都有平凡的构造函数
    • 简单地说,“普通”特殊成员函数字面上是指以非常简单的方式完成其工作的成员函数。对于不同类型的特殊成员函数,“直截了当的方式”意味着不同的事情

      对于默认的构造函数和析构函数,“微不足道”的字面意思是“什么都不做”。对于复制构造函数和复制赋值运算符,“平凡”的字面意思是“相当于简单的原始内存复制”(类似于使用
      memcpy
      复制)

      如果您自己定义一个构造函数,它被认为是非平凡的,即使它不做任何事情,因此平凡的构造函数必须由编译器隐式定义

      为了使特殊成员函数满足上述要求,类必须具有非常简单的结构,在创建或销毁对象时,它不需要任何隐藏的初始化,或者在复制对象时,不需要任何隐藏的附加内部操作

      例如,如果类具有虚拟函数,则在创建该类的对象时,它将需要一些额外的隐藏初始化(初始化虚拟方法表等),因此该类的构造函数不会被认为是微不足道的

      例如,如果一个类有虚拟基类,那么这个类的每个对象都可能包含指向同一对象的其他部分的隐藏指针。简单的原始内存复制例程(如
      memcpy
      )无法复制这样的自引用对象。需要进行额外的操作才能正确地重新初始化副本中的隐藏指针。由于这个原因,这个类的复制构造函数和复制赋值操作符将不会被认为是平凡的


      出于明显的原因,这个要求是递归的:类的所有子对象(基和非静态成员)也必须有平凡的构造函数。

      已经有了正确的答案,但下面是标准的引用(我在看到这篇文章时一直在寻找):

      (§12.1/5) 如果默认构造函数不是用户提供的,并且:
      -它的类没有虚拟函数(10.3)和虚拟基类(10.1),并且
      -其类的任何非静态数据成员都没有大括号或相等的初始值设定项,
      -它的类的所有直接基类都有普通的默认构造函数,
      -对于其类的所有类类型(或其数组)的非静态数据成员,每个此类类都有一个简单的默认构造函数

      这是来自C++11的。C++03缺少第二项,并使用隐式声明的短语,而不是用户提供的短语。在其他方面是相同的


      请注意,此规范仅涵盖微不足道的默认构造函数。“属性平凡”一词也可以在不同的上下文中使用,例如复制构造函数。

      不做任何事情。。。那么什么是复制赋值运算符?;)@acidzombie24:我对复制成员函数做了一些修改。你的第二句话我不清楚。任何用户定义的构造函数都是不平凡的,所以一旦定义了它,这个类就不再是一个POD了。我想知道我是否有一个类似于
      struct Rect1{int l,r,w,h}的结构;结构Rect2{intl,t,r,b'Rect2(){}Rect2(Rect1 r){…}将被认为是微不足道的。但我想不会,因为我不允许定义任何系数。我本以为这是允许的,因为存在一个微不足道的默认构造函数,而这不是赋值或复制operator@acidzombie24:声明任何构造函数时,将抑制默认构造函数的隐式声明。因此,您的类将根本没有默认构造函数。在C++0x之前的语言中就是这样。在C++0x,AFAIK中,您仍然可以强制编译器生成默认构造函数,这将需要一个带有关键字
      default
      的显式声明,如您的链接所示。@AndreyT:非常好的区别。如果听起来很愚蠢,很抱歉,但它也适用于析构函数吗?