Хорошая практика: постоянное и непостоянное приведение

Когда функция не изменяет аргумент объекта, я всегда заставляю ее запрашивать постоянную ссылку, даже если указанный объект не является на самом деле постоянным. Это неправильно?

Для класса-обёртки я хотел бы написать это:

template<class B>
class Wrapper{
private:
B* base_;
public:
Wrapper(const B& b) { base_ = const_cast<B*>(&b); }
void ModifyBase();
};

Конструктор не изменяет базу, поэтому он запрашивает постоянную ссылку.

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

Я чувствую, что мое решение не самое лучшее.

Есть лучший способ сделать это?

Есть ли принятая конвенция?

2

Решение

Когда вы выбираете свой параметр, чтобы быть const ссылка, вы говорите пользователю «Вы можете верить, что если вы передадите мне объект, он не будет изменен [через эту ссылку] †». Вы должны делать это как можно чаще, потому что пользователь может лучше понять, что будет с вашей функцией, а что нет, просто взглянув на типы. Кроме того, передача изменчивых ссылок может привести к коду, о котором трудно рассуждать.

Однако в вашем вопросе ваш const не говорит правду. Он отбрасывает constи хранение неconst указатель — это означает, что объект может очень хорошо измениться. Вы обманули пользователя! Неважно, что сам конструктор не делает ничего, чтобы сделать объект. Это позволяет изменять его другими функциями-членами. Это плохое поведение. Ваш конструктор не должен принимать const ссылка.

Кроме того, ваша текущая реализация допускает неопределенное поведение. Даже если объект, который первоначально объявлен как const дается вашему Wrapperэто не волнует Это отбрасывает это constи позволяет другим функциям-членам изменять его. Изменение объекта, который был изначально const является неопределенным поведением.

† См. Комментарий 6502

9

Другие решения

Это не имеет значения, что ctor не изменит объект в ctorчто происходит после ctor сделано, поэтому вам нужноconst указатель на объект B, Так что это связано с собственностью и сроком службы B объект передан в: если вы хотите стать владельцем (через & ссылка, то объект должен быть неconst потому что это может быть изменено. Если вы хотите просто скопировать B Объект передается, затем не используйте ссылку, передайте по значению и сохраните указатель на копию.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector