派生类是否间接继承了base的赋值运算符?

cod*_*ddy 3 c++ inheritance assignment-operator

我试图理解这种行为,但似乎我没有.请看这段代码:

#include <iostream>
using namespace std;

class Base
{
public:
    void operator=(const Base& rf)
    {
        cout << "base operator=" << endl;
        this->y = rf.y;
    }
    int y;
    Base() : y(100) { }
};

class Derived : public Base
{
public:
    int x;
    Derived() : x(100) { }
};

int main()
{
    Derived test;
    Derived test2;
    test2.x = 0;
    test2.y = 0;
    test.operator=(test2); // operator auto-generated for derived class but...
    cout << test.x << endl << test.y << endl;
    cin.ignore();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

计划产出:

> base operator=
>  0
>  0
Run Code Online (Sandbox Code Playgroud)

现在我感到困惑的是:规则说派生类永远不会继承分配运算符,而是创建它自己operator=但是在这个例子中operator=,在派生类上调用base .

其次,我能够在派生类上显式调用一个赋值运算符,而派生类又不是在派生类中显式定义的.

现在,如果我理解正确,这意味着任何用户定义的base的运算符总是在派生类上被调用?

Xeo*_*Xeo 12

生成的自动调用基类赋值运算符.

// generated version looks basically like this
Derived& operator=(Derived const& other){
  Base::operator=(static_cast<Base const&>(other));
  x = other.x;
  return *this;
}
Run Code Online (Sandbox Code Playgroud)

演员在那里是为了避免Base::operator=像这样的模板的召唤:

template<class Other>
Base& operator=(Other const& other); // accepts everything
Run Code Online (Sandbox Code Playgroud)

或者像这样一个奇怪的人:

// forward-declare 'Derived' outside of 'Base'
Base& operator=(Derived const& other); // accepts derived class (for whatever reason)
Run Code Online (Sandbox Code Playgroud)

其次,我能够在派生类上显式调用一个赋值运算符,而派生类又不是在派生类中显式定义的.

如果你没有,并且你的类允许它(即没有引用成员和其他一些神秘规则),编译器会自动声明赋值运算符,如果你实际在某处使用它,还会定义它.


Ben*_*igt 5

编译器生成的赋值运算符调用每个子对象的赋值运算符。这包括基类和非静态成员变量。

标准说(第 12.8 节[class.copy]):

如果类定义没有显式声明复制赋值运算符,则隐式声明一个。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制赋值运算符定义为已删除;否则,它被定义为默认(8.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不推荐使用后一种情况。类的隐式声明的复制赋值运算符X将具有以下形式

X&  X::operator=(const  X&)
Run Code Online (Sandbox Code Playgroud)

如果

  • 每个直接基类BX具有复制赋值运算符,其参数的类型的const B&const volatile B&或者B,与
  • 对于X属于类类型M(或其数组)的所有非静态数据成员,每个此类类型都有一个复制赋值运算符,其参数类型为const M&,const volatile M&M

否则,隐式声明的复制赋值运算符将具有以下形式

X&  X::operator=(X&)
Run Code Online (Sandbox Code Playgroud)

非联合类的隐式定义的复制/移动赋值运算符X执行其子对象的成员复制/移动赋值。X首先按照它们在基说明符列表中声明的顺序分配的直接基类,然后按照X它们在类定义中声明的顺序分配的直接非静态数据成员。让x是函数的任何参数,或者,对于移动运营商的x值指的是参数。每个子对象都以适合其类型的方式分配:

  • 如果子对象是类类型,就好像通过以operator=子对象作为对象表达式和x作为单个函数参数的相应子对象的调用(好像通过显式限定;也就是说,忽略更多派生类);
  • 如果子对象是数组,则以适合元素类型的方式分配每个元素;
  • 如果子对象是标量类型,则使用内置赋值运算符。

未指定表示虚拟基类的子对象是否由隐式定义的复制赋值运算符多次赋值。