Assignment operator not available in derived class

后端 未结 4 1310
甜味超标
甜味超标 2021-01-03 19:02

The assignment operator in base class does not seem to be available in derived class. Given this code:

#include 

class A{
    int value;
pub         


        
相关标签:
4条回答
  • 2021-01-03 19:14

    As pointed out by the other existing answers, the implicitly generated assignment operator of B hides the assignment operator defined in A. This is true for any non-virtual member function in a base class, the only specialty here is the automatically generated assignment operator.

    But try to figure out first whether you really want to do this. Imagine your class B has data members that need to be initialized in some way. How does using the assignment from A affect these data members? A doesn't know anything of its derived class data members, they would be left untouched. Have a look at the following scenario where the assignment operator has been made available through a using directive:

    class B : public A {
       public:
          using A::operator=;
    
          int m = 0; // Default-initialize data member to zero
    };
    
    B b;
    b.m = 42;
    b = 0; // Doesn't touch B::m... intended? A bug? Definitely weird.
    

    So yes, it is possible, but error-prone and dangerous, especially when it comes to future modifications of the subclass.

    0 讨论(0)
  • 2021-01-03 19:16

    In order to make it work, you need to bring the operator= into B's scope:

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

    According to the standard [class.copy.assign/8]:

    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 (16.5.3).

    So, because the B::operator= has been implicitly declared, it has hidden A::operator=, which requires you to bring it into scope if you want to use it.

    Further quote from the standard [over.ass/1]

    An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (15.8), a base class assignment operator is always hidden by the copy assignment operator of the derived class.

    Emphasis is mine.

    0 讨论(0)
  • 2021-01-03 19:24

    Every class has at least one assignment operator implicitly defined when we don't provide one ourselves.

    And when a member function in a derived class is defined with the same name as a member in the base class, it hides all the base class definitions for that name.

    You can use a using declaration, but be warned that it will pull all the members named operator= and allow code like this:

    A a;
    B b;
    b = a;
    

    Which is slightly dubious.

    0 讨论(0)
  • 2021-01-03 19:25

    The problem is that the compiler will add an implicit assignment operator for the B class, declared as

    B& operator=(const B&);
    

    This operator will hide the operator from A, so the compiler will not know about it.

    The solution is to tell the compiler to also use the operator from A with the using keyword:

    class B : public A
    {
    public:
        using A::operator=;
    };
    
    0 讨论(0)
提交回复
热议问题