在派生 class 中使用复制赋值

Using copy assignment in derived class

cppreference says:

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

据我了解,以下代码应该无法编译。因为

  1. B::operator=(const B&) 被隐式声明。
  2. A::operator=(const A&) 和 using 声明都被隐藏了。
#include <iostream>
using namespace std;

class A { 
 public:
    A& operator=(const A& A) {
        cout << "A::opreator=" << endl;
    }   
};

class B : A { 
 public:
    using A::operator=;
};

int main() {
    A a1; 
    B b1; 
    b1 = a1; 
}

然而,它编译成功并打印“A::operator=”,为什么?

您不能隐藏 B 的复制赋值运算符,因为您提到的两个运算符采用不同的参数。

来自 C++11 Standards#12.8 [强调]:

24 Because a copy/move assignment operator is implicitly declared for a class if not declared by the user, a base class copy/move assignment operator is always hidden by the corresponding assignment operator of a derived class (13.5.3). A using-declaration(7.3.3) that brings in from a base class an assignment operator with a parameter type that could be that of a copy/move assignment operator for the derived class is not considered an explicit declaration of such an operator and does not suppress the implicit declaration of the derived class operator; the operator introduced by the using-declaration is hidden by the implicitly-declared operator in the derived class.

class B赋值操作的隐式声明如下:

B& B::operator=(const B&)

classB中使用声明赋值运算符的参数类型与隐式声明的赋值运算符不同。因此,它抑制了派生 class B 运算符的隐式声明。

为了理解 1 和 2 w.r.t。到您发布的代码:

  1. 不,赋值运算符的隐式声明在class B.
  2. 中被禁止
  3. 不,它们不会被隐藏。

我认为你提到的参考资料应该分为两部分来满足你的 2 个问题:

  1. 是的,默认情况下隐式声明基 class (A) 和派生 class(B) 的复制赋值。您只是通过向流输出一条消息来覆盖 class A 上的隐式声明。
  2. 引用的第二部分意味着如果class B 的实例被分配给class A 的实例并且有一个使用声明使用class A赋值,则使用classA的赋值。这意味着,如果将 class B 的实例分配给 class B 的另一个实例,将使用默认的隐式分配。因此,由于参数类型的不同,没有任何内容被隐藏,代码将调用 using 声明(a.k.a 基本 class 赋值)=> 消息输出到流。

我没有发现此代码与标准有任何冲突。 b1 = a1; 此分配已完成,因为您使用了 base class 的 using-declaration。 并且“派生 class 的隐式赋值运算符”由编译器提供,因为如果你想分配派生 class 的两个对象,这是可能的。