私有拷贝构造函数/赋值运算符和复制初始化

fok*_*oke 8 c++ boost

这是这个问题的后续内容

在下面的代码中,为什么第1行编译而第2行和第3行不编译(使用visual C++ 2010)

class ABase
{
protected:
    ABase() {}
    ~ABase() {}
private:
    ABase( const ABase& );
    const ABase& operator=( const ABase& );
};

class A : ABase
{
};

class B
{
public:
    B() {}
    ~B() {}
private:
    B( const B& );
    const B& operator=( const B& );
};

int main( void )
{
    A a = A(); // line 1
    A a2( a ); // line 2
    B b = B(); // line 3

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(注意BA是boost :: noncopyable的副本)

编辑: 我的问题是不知道为什么第2行和第3行不编译(我知道,复制构造函数是私有的),但为什么第1行呢.

650*_*502 6

确实第1行不应该编译.

显然,在这种情况下,vc ++ 2010在执行语言规则时存在问题(可能是因为它们与基类有关,而与对象本身无关).

关于第1行的g ++诊断消息非常清楚

ncopy.cpp: In copy constructor ‘A::A(const A&)’:
ncopy.cpp:7: error: ‘ABase::ABase(const ABase&)’ is private
ncopy.cpp:12: error: within this context
ncopy.cpp: In function ‘int main()’:
ncopy.cpp:27: note: synthesized method ‘A::A(const A&)’ first required here 
Run Code Online (Sandbox Code Playgroud)


Dav*_*eas 5

接受第一次使用时编译器是错误的.即使删除了副本,也必须可以访问复制构造函数以使代码正确.

在这种特殊情况下,隐式声明的复制构造函数在A:

§12.8/ 4如果类定义没有显式声明复制构造函数,则会隐式声明一个.

这是隐含的定义:

§12.8/ 7隐式声明的复制构造函数是隐式定义的,如果它用于从其类类型的对象或从类类型108派生的类类型的副本初始化其类类型的对象.[注意:即使实现省略了它的使用(12.2),也会隐式定义复制构造函数.]是一个程序形成不良的,如果一个拷贝构造隐式定义的量,类有:

- 类类型(或其数组)的非静态数据成员,具有不可访问或模糊的复制构造函数,或

- 具有无法访问或模糊的复制构造函数的基类.