实现提供了复制构造函数和赋值运算符

rid*_*hap 2 c++ copy-constructor noncopyable copy-assignment

关于实现(编译器)不提供复制构造函数和复制赋值运算符的情况,我有一点混淆.

  1. 当我们在课堂上声明复制ctor和/或复制赋值运算符时.
  2. 有人说当我们从一个具有私人复制ctor和/或复制赋值运算符的类派生时.

我对第二种情况有点困惑,第二种情况正是如此.
a)实现不会为您声明它们,因此您将收到编译时错误.
或者
b)实现将声明并定义它们,但是当编译器定义的实现试图找到基类的方法时,我们将得到编译时错误.

昨天我接受了一次采访,我说(b)正在发生,但面试官不同意,他说(a).

我尝试在Microsoft C/C++ 14.00和gcc 4.4.5中编译以下代码

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

struct B : A
{
};


int main()
{
  B b1;
  B b2;
  b1 = b2;

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

Microsoft编译器输出

ctor01.cpp(9) : error C2248: 'A::operator =' : cannot access private member declared in class 'A'
ctor01.cpp(4) : see declaration of 'A::operator ='
ctor01.cpp(2) : see declaration of 'A'
This diagnostic occurred in the compiler generated function 'B &B::operator =(const B &)'
Run Code Online (Sandbox Code Playgroud)

gcc编译器输出

Ctor01.cpp: In member function ‘B& B::operator=(const B&)’:
Ctor01.cpp:4: error: ‘A& A::operator=(const A&)’ is private
Ctor01.cpp:8: error: within this context
Ctor01.cpp: In function ‘int main()’:
Ctor01.cpp:15: note: synthesized method ‘B& B::operator=(const B&)’ first required here 
Run Code Online (Sandbox Code Playgroud)

所以我认为,实现将声明并定义它,但是当编译器定义的实现试图找到基类方法时,我们将得到编译时错误.如果我错了,请纠正我.

ice*_*ime 7

关于复制构造函数,这是标准所说的(12.8/7):

如果隐式定义了复制构造函数的类具有以下内容,则程序不正确 :

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

关于复制赋值运算符(12.8/12):

如果隐式定义了复制赋值运算符的类具有以下内容,则程序不正确:

  • const类型的非静态数据成员,或
  • 引用类型的非静态数据成员,或
  • 类类型(或其数组)的非静态数据成员,具有不可访问的复制赋值运算符,或
  • 具有无法访问的复制赋值运算符的基类.

从我的观点来看,编译器如何报告错误或它实际上如何报告错误的.

但是,我确实认为答案(b)可能正确:声明了基类复制赋值,并且它是不可访问的.派生类具有隐式声明的复制赋值,如果使用,编译器将尝试定义 该复制赋值,从而使程序格式错误.