LSP иллюстрирования яркого примера (данный Дядей Входят в подкаст, который я недавно услышал) был то, как иногда что-то, что звучит правильным на естественном языке, не вполне работает в коде.
В математике, Square
Rectangle
. Действительно это - специализация прямоугольника. "", Заставляет Вас хотеть смоделировать это с наследованием. Однако, если в коде Вы сделали Square
, происходят от Rectangle
, тогда Square
должно быть применимым где угодно, Вы ожидаете Rectangle
. Это делает для некоторого странного поведения.
Предполагают, что Вы имели SetWidth
и SetHeight
методы на Вашем Rectangle
базовый класс; это кажется совершенно логичным. Однако, если Ваш Rectangle
ссылка указала Square
, то SetWidth
и SetHeight
не имеет смысла, потому что установка той изменила бы другой для соответствия ему. В этом случае Square
проваливает Тест Замены Liskov с [1 114], и абстракция наличия Square
наследовались от [1 116], плохой.
Y'all должен проверить другое бесценное ТВЕРДЫЕ Принципы Мотивационные Плакаты .
Если в вашем стандарте кодирования указано, что «помните о способах предотвращения (случайного) копирования», я предполагаю, что они говорят не только о предотвращении копий из самих классов, но и о последствиях для производительности ненужных / случайные копии, когда используют классы.
Одна из основных причин неоправданной потери производительности в коде людей, плохо знакомых с C ++, - это ненужное копирование, обычно через временные библиотеки. Компиляторы становятся все лучше и лучше в решении, когда временные не нужны (см. «Хотите скорости? Передача по значению» , благодаря комментарию Конрада), но лучше всего научиться осознавать особенности внутренняя работа копирования и временных файлов в C ++ (среди прочего). Для меня чтение Эффективный C ++ действительно помогло мне начать.
Да, если сделать оператор присваивания и конструктор копирования закрытыми, вы не сможете создавать любую копию объекта с помощью стандартных методов (но если вам действительно нужна копия объекта, вы можете реализовать, например, Копировать (), который будет выполнять глубокое копирование).
Взгляните на boost :: noncopyable .
Обновление (относительно Тала Прессмана):
... вы должны знать об этих вещах и следить за тем, чтобы случайно не скопировать объекты, которые не должны копироваться.
Я полагаю, что любое случайное копирование будет выполнено с использованием либо оператора присваивания, либо конструктор копирования. Так что сделать их частными на самом деле имеет смысл: если копирование объекта - дорогостоящая операция, то копирование должно быть явным: другой разработчик может непреднамеренно косвенно вызвать copy op, и компилятор проинформирует его,
Если вы используете ускорение, то самый простой способ предотвратить копирование класса - это унаследовать ваш класс от не копируемого :
#include <boost/noncopyable.hpp>
class Foo : private boost::noncopyable
{
}
Это проясняет ваше намерение, чем вручную сделать конструктор копирования и оператор присваивания закрытыми, и результат будет тот же.
Вы на правильном пути. Если вы не хотите использовать boost, вы можете сделать следующее: Сделать конструктор копирования и оператор присваивания копии частными и не реализовывать их. Таким образом, вы получите ошибку компилятора, если попытаетесь скопировать экземпляр.
Ваш список выглядит великолепно с точки зрения предотвращения ошибок, например, удаления одной и той же области памяти более одного раза из-за общих указателей из неявного копирования объектов.
Надеюсь, это так. также актуально; из утверждения «знайте, как можно предотвратить (случайное) копирование» вы можете принять это как означающее «осознавать непреднамеренное ненужное копирование». Это будет означать обстоятельства, которые могут повлиять на производительность. В очень простом примере ваши соглашения о кодировании могут означать, что вам следует предпочесть:
std::string text1( "some text" );
вместо:
std::string text1 = "some text";
Во втором случае будет создана временная строка для хранения «некоторого текста» перед вызовом оператора присваивания (форма копирования ), чтобы заполнить text1 «некоторым текстом».