Do derived classes indirectly inherit base's assignment operator?

孤街浪徒 提交于 2020-01-23 02:42:15

问题


I'm trying to understand this behaviour but it seems I don't. Please see this code:

#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;
}

PROGRAM OUTPUT:

> base operator=
>  0
>  0

Now where I'm confused is: The rule says that a derived class never inherits the assigment operator, instead it creates its own operator= however in this example base's operator= gets invoked on the derived class.

Second I was able to explicitly invoke an assigment operator on a derived class, which isn't in turn explicitly defined in the derived class.

Now if I understand it correctly, this means that any user defined base's operator always gets invoked on the derived class?


回答1:


The generated ones automatically call the base-class assignment operator.

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

The cast is there to avoid an accidential call to a templated Base::operator= like this one:

template<class Other>
Base& operator=(Other const& other); // accepts everything

Or a strange one like this:

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

Second I was able to explicitly invoke an assigment operator on a derived class, which isn't in turn explicitly defined in the derived class.

The compiler automatically declares an assignment operator if you do not and your class allows it (i.e., no reference members and some other arcane rules) and additionally defines it if you actually use it somewhere.




回答2:


The compiler-generated assignment operator calls the assignment operator of each subobject. That includes base classes and non-static member variables.

The standard says (section 12.8 [class.copy]):

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor. The implicitly-declared copy assignment operator for a class X will have the form

X&  X::operator=(const  X&)

if

  • each direct base class B of X has a copy assignment operator whose parameter is of type const B&, const volatile B& or B, and
  • for all the non-static data members of X that are of a class type M (or array thereof), each such class type has a copy assignment operator whose parameter is of type const M&, const volatile M& or M.

Otherwise, the implicitly-declared copy assignment operator will have the form

X&  X::operator=(X&)

and

The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy/move assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition. Let x be either the parameter of the function or, for the move operator, an xvalue referring to the parameter. Each subobject is assigned in the manner appropriate to its type:

  • if the subobject is of class type, as if by a call to operator= with the subobject as the object expression and the corresponding subobject of x as a single function argument (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes);
  • if the subobject is an array, each element is assigned, in the manner appropriate to the element type;
  • if the subobject is of scalar type, the built-in assignment operator is used.

It is unspecified whether subobjects representing virtual base classes are assigned more than once by the implicitly-defined copy assignment operator.




回答3:


That's because the implicitly defined operator = calls the base classes operator =. See the FAQ lite:

I'm creating a derived class; should my assignment operator call my base class's assignment operator?

Yes (if you need to define an assignment operator in the first place).

If you define your own assignment operator, the compiler will not automatically call your base class's assignment operator for you. Unless your base class's assignment operator itself is broken, you should call it explicitly from your derived class's assignment operator (again, assuming you create one in the first place).

However if you do not create your own assignment operator, the one that the compiler creates for you will automatically call your base class's assignment operator.




回答4:


4 things never get inherited Constructor Copy-constructor Assignment operator Destructor

Even you have not written the assignment operator your code will be Woking fine. Whenever you use assignment operator compiler will make sure that assignment operator for each member object and base class get called.



来源:https://stackoverflow.com/questions/8867469/do-derived-classes-indirectly-inherit-bases-assignment-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!