Хорошая практика: постоянное и непостоянное приведение
Когда функция не изменяет аргумент объекта, я всегда заставляю ее запрашивать постоянную ссылку, даже если указанный объект не является на самом деле постоянным. Это неправильно?
Для класса-обёртки я хотел бы написать это:
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
Это не имеет значения, что ctor
не изменит объект в ctor
что происходит после ctor
сделано, поэтому вам нужноconst
указатель на объект B
, Так что это связано с собственностью и сроком службы B
объект передан в: если вы хотите стать владельцем (через &
ссылка, то объект должен быть неconst
потому что это может быть изменено. Если вы хотите просто скопировать B
Объект передается, затем не используйте ссылку, передайте по значению и сохраните указатель на копию.