什么是编译器为一个类创build的所有成员函数? 这是否一直发生?

什么是编译器为一个类创build的所有成员函数? 这是否一直发生? 像析构函数。 我关心的是它是否为所有类创build,为什么需要默认的构造函数?

C ++ 98/03

如果他们需要,

  1. 编译器会为你生成一个默认的构造函数 ,除非你声明了你自己的构造函数。
  2. 编译器会为你生成一个拷贝 构造函数 ,除非你自己声明。
  3. 编译器将为您生成一个复制 赋值运算符 ,除非您声明自己的。
  4. 编译器会为你生成一个析构函数 ,除非你自己声明。

正如佩特在有用的评论中所说的那样,所有这些只有在需要的时候才由编译器生成。 (不同之处在于,当编译器无法创build它们时,只要不使用它们即可)。


C ++ 11

C ++ 11添加了以下规则,对于C ++ 14也是如此(请参阅towi,请参阅此注释 )

  • 编译器生成移动 构造函数 if
    • 没有用户声明的拷贝 构造函数 ,并且
    • 没有用户声明的复制 赋值操作符 ,并且
    • 没有用户声明的移动 赋值运算符
    • 没有用户声明的析构函数
    • 不被标记为已删除
    • 所有的成员和基地都是可移动的
  • 移动 赋值运算符类似:如果没有用户定义,则会生成它
    • 没有用户声明的拷贝 构造函数 ,并且
    • 没有用户声明的复制 赋值操作符 ,并且
    • 没有用户声明的移动 构造函数
    • 没有用户声明的析构函数
    • 不被标记为已删除
    • 所有的成员和基地都是可移动的

请注意,这些规则比C ++ 03规则稍微详细一些,在实践中更有意义。

为了更容易理解上面这些东西是什么Thing

 class Thing { public: Thing(); // default constructor Thing(const Thing&); // copy c'tor Thing& operator=(const Thing&); // copy-assign ~Thing(); // d'tor // C++11: Thing(Thing&&); // move c'tor Thing& operator=(Thing&&); // move-assign }; 

作为进一步阅读,如果你是一个C ++初学者,考虑一个devise,不需要你实现过去五年中的任何一个,即零规则 (由Martinho Fernandes提供 )

你的意思是“定义”“创造”?

$ 12.1 – “默认的构造函数(12.1),复制构造函数和复制赋值运算符(12.8)和析构函数(12.4)是特殊的成员函数。

如果“创build”意味着“定义”,那么这里是C ++标准的重要部分。

– 当一个类被隐式声明的缺省构造函数被用来创build它的类types(1.8)的对象时被隐式定义。

– 如果一个类没有用户声明的析构函数,则析构函数被隐式声明。 隐式声明的析构函数在用于销毁其类types的对象时被隐式定义。

– 如果类定义没有显式声明一个拷贝构造函数,则隐式地声明它。 隐式声明的拷贝构造函数是隐式定义的,如果它被用来从它的类types的对象的副本或从它的类types派生的类types的初始化它的类types的对象)。

– 如果类定义没有明确声明一个复制赋值运算符,则隐式声明一个。 隐式声明的复制赋值运算符在其类types的对象被赋予其类types的值或从其类types派生的类types的值时被隐式定义。

默认情况下,如果用户没有实现,编译器会向类中添加一些成员函数。 那些被称为四大:

  • 默认的构造函数
  • 复制构造函数
  • 复制操作员(作业)
  • 析构函数

根据成员的types以及您自己提供的成员函数,将不会生成所有成员函数。

其他答案已经告诉你什么是创build的,编译器可能只生成它们,如果使用。

我关心的是,它是否为所有的课程创build…

为什么要关心 认为这是在可执行文件中创build不需要的代码? 不太可能,但你可以很容易地检查你的环境。

或者也许你的担心是,它可能不会创build一个构造函数,当你想要一个? 没有什么可担心的…它们总是在需要时创build,而不是由用户提供。

…为什么需要默认的构造函数?

因为类中可能有自己的析构函数,需要系统地调用它们。 例如,给定…

 struct X { std::string a; std::string b; }; 

…默认的析构函数确保a和b的析构函数运行。