Strange behaviour of operator= in C++
Asked Answered
G

1

7

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.

Galway answered 18/4, 2020 at 15:53 Comment(1)
Is B::operator= supposed to take an A instead of a B?Hydrophone
S
10

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.

Sisco answered 18/4, 2020 at 15:58 Comment(2)
That makes totally sense, thank you. I tried "B& operator=(const B&) = delete" to trick-force the other operator=(), but unfortunately this doesn't work. But having two operators is not a big problem anyway.Galway
A function declared deleted still participates in overload resolution. If it's actually chosen, the program is ill-formed.Sisco

© 2022 - 2024 — McMap. All rights reserved.