2

cppreference

因为总是为任何类声明复制赋值运算符,所以基类赋值运算符总是隐藏的。如果使用 using-declaration 从基类引入赋值运算符,并且其参数类型可以与派生类的隐式赋值运算符的参数类型相同,则 using-declaration 也被隐式隐藏宣言。

据我了解,以下代码不应编译。因为

  1. B::operator=(const B&) 是隐式声明的。
  2. A::operator=(const A&) 和 using-declaration 都是隐藏的。
#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=”,为什么?

4

4 回答 4

1

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

于 2020-06-23T01:44:06.307 回答
1

来自C++11 标准#12.8 [强调添加]

24 因为如果用户未声明复制/移动赋值运算符,则为类隐式声明,因此基类复制/移动赋值运算符始终被派生类的相应赋值运算符隐藏(13.5.3)。从基类引入赋值运算符的 using-declaration(7.3.3),其参数类型可能是派生类的复制/移动赋值运算符的类型,不被视为此类运算符的显式声明,而是不抑制派生类运算符的隐式声明;using 声明引入的运算符被派生类中隐式声明的运算符隐藏。

赋值操作的隐式声明class B将是这样的:

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

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

为了理解您发布的代码的 1 和 2:

  1. 不,赋值运算符的隐式声明在 class 中被禁止B
  2. 不,它们不会被隐藏。
于 2020-06-23T08:48:27.973 回答
0

我认为您提到的参考应该分为适合您的 2 个问题的 2 个部分:

  1. 是的,基类 (A) 和派生类 (B) 的复制分配默认是隐式声明的。您只需通过将消息输出到流来覆盖 A 类的隐式声明。
  2. 引用的第二部分表示如果将 B 类的实例分配给 A 类的实例,并且有使用 A 类赋值的 using 声明,则将使用 A 类的赋值。这意味着,如果将 B 类的一个实例分配给 B 类的另一个实例,则将使用默认的隐式分配。因此,由于参数类型的不同,没有任何东西被隐藏,并且代码将调用 using-declaration(也称为基类分配)=> 消息输出到流。
于 2020-06-23T09:11:19.447 回答
0

我看不出这段代码与标准有任何冲突。b1 = a1; 完成此分配是因为您使用了基类的 using 声明。并且“派生类的隐式赋值运算符”也是由编译器提供的,因为如果你想分配派生类的两个对象,这是可能的。

于 2020-06-23T09:12:32.097 回答