Search code examples
c++inheritanceassignment-operator

Strange behaviour of operator= in C++


I have a base class A and two derived classes B and C. B defines the = operator, taking the base class A as parameter.

When calling = on class B, sometimes the operator of base class A is called instead of the one from B.

class A {
        public:

        void operator=(A &) {
                printf("A =\n");
        };
};

class B : public A {

        public:

        void operator=(A &s) {
                printf("B =\n");
        };
};

class C : public A {
};

int main()
{
        B b1, b2;
        C c;

        b1 = b2;
        b1 = c;
}

Output is:

A =
B =
  • Why is the first assignment not calling B::operator=()?

  • Why is the second assignment not calling A::operator=() as well, as it is also derived from A?

  • What can i do to make B::operator=() be called every time?

I was totally surprised when i saw this. I noticed it only because i deleted operator=() ("operator=() = delete") in class A, leading to a compiler error.


Solution

  • Your B::operator= is not a copy-assignment operator. In addition to the one you provide, there's also an implicitly-defined copy-assignment operator that is equivalent to

    B& operator=(const B& other) {
      A::operator=(other);
      return *this;
    }
    

    This operator doesn't print anything, but it calls the assignment on the base class, and that one prints A=.

    b1 = b2 calls this copy-assignment operator. b1 = c calls B::operator=(A&) since C is not a B.

    If you want your operator to be called, define a copy-assignment operator with the signature shown above, instead of or in addition to the other overload.