2012-06-01 233 views
1

根据“内部C++对象模型”,只有在以下四个条件中至少有一个条件为真时,才会生成复制构造函数(如果程序员未声明):什么时候在C++中生成默认构造函数

  1. 当类包含一个复制构造函数存在的类的成员对象时(或者由类设计器显式声明,就像前一个String类的情况一样,或者由编译器合成) Word类)

  2. 当这个类是从一个复制构造函数存在的基类派生的(同样,明确地声明或合成的)

  3. 当类声明一个或多个虚拟功能

  4. 当类是从其中一个或多个基类是虚拟继承链衍生

这意味着如果我只有构造函数的类,那么复制构造函数将不会被编译器提供。

让我们举个例子:

class test 
{ 
    test(){} 
}; 
int main() 
{ 
    test obj1;  //statement 1 
    test obj2(obj1); //statement 2 
} 

上面的代码工作正常。现在问题来了,当我在类测试中添加以下行:

test(const test& rhs) = delete; 

“= delete”确保复制构造函数不会自动提供。添加上面的行后,我得到一个错误报告说2 Use of deleted function test::test(const test&)。我的问题是:按照“内部C++对象模型”我不需要上述类的复制构造函数,所以当我明确说不生成复制构造函数(使用删除)为什么我得到一个错误?因为我期待编译器不需要上述类的复制构造函数。

我使用的是gcc版本4.6.3。

+1

如果没有提供_copy-constructor_,那么您的语句2将不会编译。 –

+0

它工作正常,如果我不添加测试(常量测试和rhs)在课堂上。 – user1431221

+0

语句2不使用默认构造函数,它使用复制构造函数,并且如果声明了它并将其删除(您所做的),那么它将不会编译,因为语句2会匹配已删除的签名。 – birryree

回答

0

这条线:

test obj2(obj1) 

试图调用拷贝构造函数。

8

对于类是可复制的,它需要有一个复制构造函数。无论你自己编写,还是编译器为你生成一个,都没关系 - 它必须可用于test a; test b(a);才是有效的操作。

您明确强制编译器删除复制构造函数 - 这是旧版本的“make copy constructor private”技巧的新版本。它禁止复制。所以不要惊讶,你不能复制。因为你告诉编译器不允许它。

2

标准字上隐式生成复制构造是[class.copy]/7

如果类定义不明确地声明一个拷贝构造,一种是隐式地声明。如果类定义声明了移动构造函数或移动赋值操作符,则隐式声明的拷贝构造函数被定义为删除;否则,它被定义为默认(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况。

[class.copy]/13

被默认和未限定的复制/移动构造为已删除的隐式定义的,如果它是ODR使用(3.2),或当它在首次声明后明确默认。 [注意:即使实现忽略了odr用法(3.2,12.2),也会隐式地定义复制/移动构造函数。 -end note]如果隐式定义的构造函数满足constexpr构造函数的要求(7.1.5),则隐式定义的构造函数isconstexpr。

所以一个拷贝构造test仍会生成,其过得去声明2.调用我会相信“内部C++对象模型”在谈论当拷贝构造不不重要的。

+0

描述了拷贝ctor是否被声明为_declared_,关于何时隐式地_defined_(即生成) –

相关问题