Коллега и я обсуждаем, являются ли постоянные или ссылочные члены правильным решением. константные и ссылочные члены делают класс не копируемым и неподвижным, если вы не напишите свой собственный оператор копирования и перемещения, который игнорирует ссылочные или константные члены. Я не могу найти случай, когда игнорирование копирования или перемещения определенных членов только потому, что они являются ссылками или const, имеет смысл.
Я думаю, что наличие неподвижного объекта очень редко логично, и это выбор, который имеет отношение только к тому, инвариант местоположения. Некопируемый объект встречается гораздо чаще, но выбор сделать некопируемый класс зависит от того, содержит ли он ресурс, который является логически не копируемым, если он представляет единоличное владение и т. Д. Я не могу придумать причину единственной черты наличие ссылки или константного члена или нет будет означать, что класс должен имеют одну из этих черт (не копируемую или неподвижную)
Должны ли они Когда-либо использоваться? Должен ли один, но не другой? Какие есть примеры?
Я не могу придумать причину, по которой единственная черта наличия ссылки или константного члена подразумевает, что у класса должна быть какая-либо из этих черт (не копируемая или неподвижная)
Я думаю, что предпосылка неверна.
Иметь const
элемент данных или элемент ссылочных данных не делает класс недоступным для копирования: он просто делает невозможным назначать это или отойти от него разрушительным образом.
Это потому, что разрушительная операция перемещения не const
объекты или ссылки: это было бы против их семантики, так как состояние const
объект никогда не должен изменяться, и ссылки не могут быть связаны.
Однако тот факт, что X
не может быть назначен для копирования или перемещения, не ставит под угрозу возможность строительство копии этих объектов, что, как вы указываете, является звуковой операцией. Следующая программа, например, будет компилироваться нормально:
struct X
{
X() : x(0), rx(x) { }
const int x;
const int& rx;
};
int main()
{
X x;
X x1 = x; // Copy-initialization (copy-constructs x1 from x)
X x2 = X(); // Copy-initialization (copy-constructs x2 from a temporary)
}
Компилятор сгенерирует для вас неявно конструктор копирования, а переместится в копии. Если вырождение перехода в копию не подходит для семантики вашего класса, вы можете подумать, что const
или ссылочные члены.
Других решений пока нет …