Странное поведение оператора = в C ++ - PullRequest
7 голосов
/ 18 апреля 2020

У меня есть базовый класс A и два производных класса B и C. B определяет оператор =, принимая в качестве параметра базовый класс A.

При вызове = в классе B иногда вызывается оператор базового класса A вместо оператора из 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;
}

Вывод:

A =
B =
  • Почему первое назначение не вызывает B :: operator = ()?

  • Почему второе присваивание, не вызывающее A :: operator = (), а также полученное из A?

  • Что я могу сделать, чтобы каждый раз вызывать B :: operator = () время?

Я был совершенно удивлен, когда увидел это. Я заметил это только потому, что я удалил operator = () ("operator = () = delete") в классе A, что привело к ошибке компилятора.

1 Ответ

10 голосов
/ 18 апреля 2020

Ваш B::operator= не является оператором копирования. В дополнение к предоставленному вами, есть также неявно определенный оператор копирования-присвоения, который эквивалентен

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

Этот оператор ничего не печатает, но вызывает назначение базового класса, и тот, кто печатает A=.

b1 = b2, вызывает этот оператор назначения копирования. b1 = c звонки B::operator=(A&), поскольку C не является B.

Если вы хотите, чтобы ваш оператор вызывался, определите оператор назначения копирования с подписью, показанной выше, вместо или в дополнение к другой перегрузке.

...