#c
#c
Вопрос:
В моем учебнике говорится, что виртуальные операторы присваивания «открывают новую банку червей, выходящую за рамки учебного пособия».
Можно сделать оператор присваивания виртуальным. Однако, в отличие от случая с деструктором, где виртуализация всегда является хорошей идеей, виртуализация оператора присваивания действительно открывает мешок, полный червей, и затрагивает некоторые сложные темы, выходящие за рамки этого руководства. Следовательно, мы собираемся рекомендовать вам пока оставить ваши назначения невиртуальными, в интересах простоты.
Что это значит? Можете ли вы объяснить, о каких проблемах говорится в книге, на небольшом примере? Почему виртуальные операторы присваивания являются особенными?
Комментарии:
1. В общем, оператор присваивания и наследование вместе — плохая идея, так много всего может пойти не так, если не учитывать это должным образом, например, усечение объекта. И это перед добавлением виртуального наследования в микс, который умножает особые случаи, чтобы получить право.
2. было бы хорошо, если бы вы могли обобщить или предоставить ссылку на пример, о котором идет речь в руководстве, для контекста
3. отредактировано, запрос ссылок или сторонних ресурсов считается оффтопическим
4. Найдите в Интернете «C object slicing».
5. Хорошо, я сделаю, спасибо @ThomasMatthews !
![]()
Ответ №1:
Давайте возьмем классический пример формы:
class Shape
{
public: virtual bool operator==(const Shape amp; s) const = 0;
};
class Rectangle : public Shape
{
public: bool operator==(const Shape amp; s) const
{ /*...*/ }
};
class Circle : public Shape
{
public: bool operator==(const Shape amp; s) const
{ /*...*/ }
};
Теперь начинается самое интересное.
Rectangle r;
Circle c;
Shape * p_shape1 = amp;r; // This is legal.
Shape * p_shape2 = amp;c; // So is this.
// What happens here????
if (r == *p_shape2)
{
//...
}
ИМХО, операторы не должны наследоваться. Нет никакой гарантии, что операторы Child1 будут переданы экземплярам Child1; Они могут быть переданы экземплярам Child` или Child3 или даже экземплярам GrandChild1.
Комментарии:
1. С присваиванием еще интереснее!
2. Это не относится к операторам. Функция определена так, чтобы принимать
Shape constamp;
аргумент, и это все, что она может принять. Написание виртуального оператора равенства обычно включаетdynamic_cast
. В любом случае, однако, OP спрашивал об операторе присваивания.