Безопасно ли использовать сгенерированный компилятором оператор присваивания? - PullRequest
3 голосов
/ 20 декабря 2008

Я использую класс CPoint из MFC. Не существует явно определенного оператора присваивания или конструктора копирования (AFAIK). Тем не менее, это работает:

CPoint p1(1, 2), p2;
p2 = p1; // p2 now is equal to p1

Я предполагаю, что это работает автоматически из-за сгенерированного компилятором оператора присваивания. Правильно?

Если так, могу ли я быть уверен, что это не делает ничего неожиданного? В этом случае CPoint настолько прост, я думаю, что все хорошо, но в целом это то, что меня немного беспокоит. Что лучше сделать:

p2.SetPoint(p1.x, p2.x);

-cr

Ответы [ 7 ]

4 голосов
/ 20 декабря 2008

Это безопасно - если оператор присваивания не должен быть предоставлен, то разработчики MFC могли бы убедиться, что он недоступен (например, сделав его закрытым).

IIRC компилятор выполнит копирование по элементам, поэтому для класса, содержащего POD, подобного этому, у вас не возникнет проблем. Это может запутаться, если у вас есть класс, который выделяет память и игнорирует переопределение оператора = и выполнение глубокого копирования.

FWIW Я задал вопрос о том, что компилятор может и не может сделать некоторое время назад:

Почему компиляторы C ++ не определяют operator == и operator! =?

Некоторые ответы интересны для чтения.

3 голосов
/ 20 декабря 2008

Поиск конструктора копирования по умолчанию:

http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html

Это не особенность CPoint.

1 голос
/ 20 декабря 2008

Если класс «простой», то сгенерированный компилятором оператор присваивания будет работать (для каждого элемента). Если есть некоторые члены, которые требуют более продвинутой логики (скажем, объект поддерживает внутренний указатель на то, что он ожидает, это частный буфер), то у оператора присваивания, сгенерированного компилятором, будут проблемы. CPoint просто хранит координаты x и y точки, поэтому вы не должны сталкиваться с проблемами.

0 голосов
/ 20 декабря 2008

Да. Если вы не определили метод operator= для класса, компилятор сгенерирует для вас метод, который просто делает побитовую копию полей в классе. Насколько я помню, CPoint это просто {int x; int y}, и поэтому побитовое копирование в порядке.

0 голосов
/ 20 декабря 2008

Для простого объекта данных, такого как CPoint (который вы можете видеть из источника MFC, включенного в вашу установку Visual Studio, является просто структурой Win32 POINT с несколькими прикрепленными вспомогательными функциями), нет ничего плохого в использовании сгенерированного компилятором оператор присваивания.

Но, как уже упоминалось, оператор присваивания по умолчанию является поверхностной копией, и вы столкнетесь с проблемами, если структура содержит указатели (или содержит структуры, содержащие указатели без определения оператора присваивания). Поскольку CPoint не подходит под это описание, это безопасно.

0 голосов
/ 20 декабря 2008

Встроенный оператор назначения копирования просто копирует каждого члена по очереди, используя их операторы назначения копирования. Я предполагаю, что это безопасно для CPoint, не смотря на его документацию (причина: если бы это было не так, они бы предоставили собственную реализацию, конечно) Этот класс точек должен иметь только два члена (x и y), и это просто числа с плавающей точкой (или int, в зависимости от того, что он использует).

Кто-то говорит, что это «мелкая копия», поскольку копируются только значения членов. Если у вас есть элементы указателя, значения указателя копируются вместо объектов, на которые указывают указатели.

0 голосов
/ 20 декабря 2008

Я не знаю MFC, но могу предположить, что (альтернативно):

  • CPoint имеет определенный оператор присваивания (поэтому не генерируется компилятором), или
  • Оператор присваивания, сгенерированный компилятором, работает, когда элементы размещены в стеке, поэтому он выполняет копирование по элементам.
...