Как я могу заставить класс const правильно работать со ссылочными данными?

avatar
Peter Fletcher
1 июля 2021 в 21:30
48
0
1

Допустим, у меня есть класс изображения, который ссылается на буфер, содержащий огромное количество данных.

При вызове конструктора копирования было бы неплохо не копировать данные, если в этом нет крайней необходимости.

Однако, если я создаю новый объект изображения из существующего константного объекта, новый объект изображения начинается в неконстантном состоянии, что позволяет изменять данные изображения в новом объекте, даже если данные изображения в старом объект не мог.

Я полагаю, что это фундаментальная проблема в C++, потому что объект shared_ptr имеет ту же проблему: если вы получили константный shared_ptr, вам нужно только скопировать его в неконстантный объект shared_ptr (через конструктор), чтобы получить изменчивый объект, который кажется коварным способом противодействия константной правильности. Необработанные указатели не имеют этой проблемы, поскольку такая копия не разрешена.

Я понимаю, что члены-указатели по своей природе не наследуют константность от своего владельца, но то, что мне нужно, — это способ построить класс, чтобы он выглядел так, чтобы было легко гарантировать, что содержимое константного объекта остаются постоянными

Этот вопрос дает частичный ответ на этот вопрос, поскольку он предлагает использовать std::experimental::propagate_const, чтобы убедиться, что указатель в константном объекте становится константным указателем:

Как сделать указатель с глубокой константой

Однако я считаю, что это не решает проблему того, как гарантировать, что конструктор копирования с константным объектом, явно указывающим на константные данные, становится объектом, который не может изменять указанные данные.

Источник
Sam Varshavchik
1 июля 2021 в 21:53
1

Если вы задумаетесь о существовании iterator и const_iterator и о том, какие из них можно построить из других, станет возможным один потенциальный подход. В любом случае вы не можете «гарантировать, что конструктор копирования с константным объектом, явно указывающим на константные данные, станет объектом, который не может изменить указанные данные». С++ так не работает на фундаментальном уровне.

Davis Herring
2 июля 2021 в 06:26
1

Вам не нужно копировать const std::shared_ptr<…>, чтобы получить непостоянный доступ к указанному объекту: * уже сделает это. У указателей просто есть два (или более) места для размещения const; это это позор, что система типов не позволяет нам автоматически преобразовывать интеллектуальные указатели всеми способами, которыми мы можем использовать необработанные указатели, но вы определенно можете написать std::const_pointer_cast<const …>(sp) для обеспечения const через std::shared_ptr, так что это может не соответствовать «фундаментальной проблеме».

Ответы (0)