2010-10-03 143 views
3

我知道如果拷贝ctor在类中声明为private,编译器将不会生成默认拷贝ctor。C++默认拷贝构造函数

但是有人能解释为什么编译器会这么做吗?

如果复制ctor被声明为受保护会发生什么?编译器会提供默认的copy ctor吗?

如果复制ctor被声明为私有但有一个定义例如foo(const & obj){}

回答

4

在类中声明的任何拷贝构造函数(无论是私有的,公共的还是受保护的)都意味着编译器不会生成默认的拷贝ctor。无论是在类中声明的那个定义还是定义,或者不仅控制具有适当可见级别代码的代码是否可以复制该类的实例(如果未定义,链接器会投诉;编译器的工作仅仅是抱怨使用没有适当的知名度,不要复制链接器的工作)。

例如,如果您声明私人副本ctor,则只有在类中的函数(或朋友,当然)中的代码被允许编译,如果它试图复制实例。如果没有定义ctor,那么该代码将无法在链接器中生存下来,因此无论如何你都会得到一个错误(不幸的是,在构建过程中稍后会出现这种情况,也就是说,与之前相比,构建时可能会略微浪费计算资源 - 检测到的错误)。

2

编译器知道存在一个拷贝构造函数,所以它不会生成一个拷贝构造函数。无障碍(公共/私人/受保护)或其是否有定义在此阶段不予考虑。

听起来好像没有复制构造函数就是因为你不能从外部和非朋友调用私人函数。用户定义的构造函数仍然存在,只是它是私人的。

如果它被保护,那么只有子类和它本身可以调用复制构造函数。也不会有隐式定义的拷贝构造函数。

0

只要显式声明了复制构造函数,编译器就不会生成默认的复制构造函数。无论明确声明具有什么隐私级别(私有,受保护或公开),情况都是如此。

1

$ 12月1日 - “默认构造函数 (12.1),拷贝构造函数和拷贝 赋值运算符(12.8),和 析构函数(12.4)是特殊的成员 函数[注:执行 会。当 程序没有明确 宣布他们含蓄地宣布对某些类类型这些成员 功能。实施将 隐含地定义他们,如果他们使用 。 [...]”

因此,如果拷贝构造函数是显式声明的,编译器会将其作为具有自定义拷贝构造函数的意图,并且隐式拷贝构造函数的生成被抑制。

复制构造函数可以声明并定义为私有。如果复制构造函数被定义为私有,则复制初始化/直接初始化将不起作用,如下所示。

struct A{ 
    A(){} 
private: 
    A(A const &){} 
}; 

int main(){ 
    A a1; 
    A a2(a1); // direct initialization, error 

    A a3 = a1; // copy initialization, error 
}