Const корректность функции-члена, возвращающая shared_ptr <>
если у меня есть класс
class foo {
private:
std::shared_ptr<char> m_data;
public:
std::shared_ptr<const char> GetData()
{ return m_data;}
}
Я считаю, что std::shared_ptr< T >
должен отбрасываться на std::shared_ptr< const T >
и делиться одним и тем же объектом, но что такое константная корректность функции?
IE
- это действительно?
std::shared_ptr<const char> GetData() const;
Ответы
Ответ 1
Это означает, что безопасно отмечать его как const
.
* Примечание: @Yakk правильно указал в комментариях, что для некоторого определения "внутреннего состояния" функция действительно модифицирует его, поскольку он увеличивает счетчик ссылок на char
, принадлежащий общему указателю m_data
. Вы должны сами решить, является ли это неконстантной операцией; строго по правилам языка, это не так (потому что он изменяет то, на что указывает shared_ptr
, а не сам shared_ptr
). Но поскольку вы сначала сохраняете shared_ptr
, я предполагаю, что вы в порядке с разделяющим правом собственности, поэтому его нельзя рассматривать как модификацию.
Ответ 2
Вы должны быть очень осторожны с таким кодом. В состоянии, в котором находится ваш код в настоящий момент, все будет в безопасности, потому что вы только обертываете shared_ptr
, и никто не может изменять содержимое, потому что они являются частными. Однако, если вы расширяете свой код, есть тонкая, но серьезная ошибка, которую трудно отладить: если вы добавляете функции, которые изменяют данные, на которые указывают теги shared_ptr
, тогда код, которому уже принадлежит shared_ptr
, на const char
из вашей функции GetData()
будут отображаться измененные данные, а не копия данных.
В С++ ключевое слово const
действительно означает только для чтения и не является неизменным, как многие думают, когда они впервые узнают об этом. Способ сделать ваш код будущим - это использовать std::shared_ptr<char>
как тип данных для вашего члена данных m_data
. Если это не подходит для ваших требований к вашему коду, подумайте о том, чтобы просто вернуть полную копию своих данных при вызове функции GetData()
. Реализация copy-on-write может потребоваться, если у вас есть плохие ограничения производительности, но если вы не уверены в этих штрафах за производительность, избегайте копирования на запись, потому что это сложно из-за вышеприведенных причин.