By Montaner


2019-02-06 10:44:25 8 Comments

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

#include <iostream>

class A{
    int value;
public:
    A& operator=(int value){
        this->value = value;
        return *this;
    }
};

class B : public A{};

int main(){
    B b;
    b = 0; // Does not work
    return 0;
}

GCC 6.4 says:

error: no match for 'operator=' (operand types are 'B' and 'int')

What is happening?

4 comments

@lubgr 2019-02-06 10:49:20

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.

@spectras 2019-02-06 10:51:42

It does not behave differently, the same issue will arise with any other method.

@user463035818 2019-02-06 10:54:56

@spectras "same issue" ?? usually mehtods are inherited by derived classes and can be used without further measures. Any other method will not be implicitly declared by the compiler

@spectras 2019-02-06 10:56:15

@user463035818 the issue here is name hiding. See Some programmer dude's answer. You'll encounter this issue anytime a method in derived class has the same name as methods in base class ^^

@user463035818 2019-02-06 10:57:48

@spectras ok, thanks, now I understand what you mean, though OP didnt declare a operator= in the derived and it is special with regard to hiding

@lubgr 2019-02-06 10:58:34

@spectras Thanks for pointing that out, I fixed this part of the answer.

@naomimyselfandi 2019-02-06 14:51:43

The best answer, imo, since it addresses why hiding the assignment operator is desirable, and the caveats with dragging it in.

@Mark Ingram 2019-02-06 10:48:27

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.

@Some programmer dude 2019-02-06 10:48:45

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

@spectras 2019-02-06 10:50:17

Isn't this only true because of the implicitly declared copy assignment in B hiding A::operator=?

@Some programmer dude 2019-02-06 10:52:45

@spectras Yes that's true, which is why I updated the answer (just when you posted the comment).

@StoryTeller 2019-02-06 10:50:10

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.

@Tas 2019-02-06 22:50:19

I actually had to read Mark's answer to make sense of your second paragraph, but once I understood that your answer is very informative.

Related Questions

Sponsored Content

21 Answered Questions

[SOLVED] What is the "-->" operator in C++?

10 Answered Questions

4 Answered Questions

6 Answered Questions

[SOLVED] How to call a parent class function from derived class function?

  • 2008-12-10 19:35:45
  • IaCoder
  • 513358 View
  • 505 Score
  • 6 Answer
  • Tags:   c++ oop inheritance

7 Answered Questions

1 Answered Questions

1 Answered Questions

[SOLVED] How to call derived assignment operator from base class?

2 Answered Questions

[SOLVED] C++ assignment operator in derived class

1 Answered Questions

1 Answered Questions

[SOLVED] Method of derived class needs to downcast its parameter

  • 2010-01-30 15:56:29
  • Ivan Virabyan
  • 528 View
  • 1 Score
  • 1 Answer
  • Tags:   c++

Sponsored Content