Derived class inherit base class assignment operator?

亡梦爱人 提交于 2019-11-29 16:07:56

The compiler generates a default assignment operator for Derived (which hides the operator of Base). However, the default assignment operator calls all assignment operators of the class' members and base classes.

Yes it does it is just that the Base class = operator is hidden by the Derived class = operator.

Unless I misunderstand what you want to achieve, you need an assignment operator for class Derived, i.e. one that takes Derived as the input:

class Derived : public Base  
{  
/* ... */
public:
    Derived& operator=(const Derived &rhs)  
    {  
        cout << "Assignment operator in Derived"<< endl;  
        return *this;  
    }
};  

What happened within your code (already explained in the answer of Bo Persson and comments there): in Derived, you implemented an assignment operator that takes an instance of Base; but in main() you assign an instance of Derived; the compiler saw no assignment operator for Derived (the one that takes Base does not count), and so it generated one, which calls Base::operator=() and then assignments for Derived's data members. If you defined the assignment as shown above, it would not happen and your operator would be called; notice that in this case assignments of Base and data members would not happen automatically.


A different situation is if you really wish to have an assignment from Base to Derived, e.g. to use it with other derivatives of Base. Then the operator you defined will work, but in order to apply it to an instance of Derived, you need to cast this instance to Base:

Derived d1(10,20);  
Derived d2(30,40);  
d1 = static_cast<Base&>(d2);

Needless to say that the operator you defined cannot easily access data members of rhs specific to Derived: e.g. to use rhs.y you would need to "up-cast" rhs to Derived:

Derived& Derived::operator=(const Base& rhs)
{
    /* ... */
    Derived* rhs_d = dynamic_cast<Derived*>(&rhs);
    if( rhs_d )
        this->y = rhs_d->y;
}

Quoting from the standard (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.

If you wanted to achieve polymorfic behavior, this means to have your base method overriden, you should have written this:

int main (){
    Derived * d1 = new Derived (10,20);  
    Derived * d2 = new Derived (30,40);
    Base * b1 = d1 ;
    Base * b2 = d2 ; 
    *b1 = *b2 ;
    *d1 = *d2 ;
} 

This will produce the following output:

 $> Assignment operator in Derived.
 $> calling Assignment operator in Base. 

So what i'm doing here it's using the c++ dynamic casting implicitly. I not completely sure if this works this way, but in order to make my point i think it will be useful. When i call the assignment operator with b1 and b2 dereferenced, the program first look for an overriden method of the function invoked on the derived class if it doesn't find any then it calls the base method class. Now, when i call the assignment operator from d1 the program casts derived to base and there's no way the program could know that *d1 stands for a Derived object, so it calls the base method.

That's all folks.

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