Общеизвестно, что при реализации оператора присваивания нужно защищать от самоназначения, по крайней мере, когда в классе есть не-POD члены. Обычно это (или эквивалентно):
Foo& operator=(const Foo& other)
{
if (&other == this)
return *this;
... // Do copy
}
По каким причинам вы не включили автоматическую защиту автоматически? Существуют ли случаи использования, когда самостоятельное назначение делает что-то нетривиальное и практически полезное?
Foo& operator=(const Foo& other)
{
if (&other == this)
{
// Do something non-trivial
}
else
{
// Do copy
}
return *this;
}
Подведем итоги и обсудим к настоящему моменту
Похоже, нетривиальное самостоятельное назначение никогда не может быть действительно полезным. Единственный предложенный вариант заключался в том, чтобы поместить туда assert
, чтобы обнаружить некоторые логические ошибки. Но есть вполне законные случаи самостоятельного назначения, такие как a = std::min(a, b)
, поэтому даже эта опция весьма сомнительна.
Но есть две возможные реализации тривиального самостоятельного назначения:
- Ничего не делать, если
&other == this
. Всегда работайте, хотя может иметь негативное влияние на производительность из-за дополнительного ветвления Но в определяемом пользователем операторе присваивания тест должен выполняться почти всегда явно.
- Скопируйте каждого члена в себя. Это то, что сделано по умолчанию. Если члены также используют операторы назначения по умолчанию, это может быть быстрее, потому что не требует дополнительного ветвления.
Я до сих пор не понимаю, почему стандарт C ++ не может гарантировать это в пользовательском операторе присваивания &other != this
. Если вы не хотите разветвления, используйте оператор по умолчанию. Если вы переопределяете оператора, в любом случае требуется некоторый тест ...