#c #constants #smart-pointers #copy-constructor
#c #константы #интеллектуальные указатели #копировать-конструктор
Вопрос:
Я пишу реализацию интеллектуального указателя на C , и у меня возникли некоторые проблемы с корректностью const. Ниже приведен отрывок из кода:
template <class T> class Pointer {
T* pointee;
public:
Pointer(const Pointer<T>amp; other) { // must be const Pointeramp; for assignments
pointee = other.getPointee();
}
T* getPointee() const {
return pointee;
}
};
Это один из способов сделать это, однако я чувствую себя неловко const
, что член не возвращает const
указатель. Другой возможностью было бы разрешить getPointee()
возвращать a const T*
и выполнять a const_cast<T*>
в конструкторе копирования.
Есть ли лучший способ сделать это? Если нет, что, по вашему мнению, является меньшим злом, возвращая неконстантное значение или выполняя a const_cast
?
Комментарии:
1. Есть ли особая причина, по которой вы пытаетесь написать свой собственный интеллектуальный указатель. В большинстве случаев те, которые предусмотрены стандартом, отлично справляются со своей задачей.
2. Да, есть. Я использую внутренний подсчет ссылок в своих объектах.
3. Boost предоставляет навязчивый интеллектуальный указатель: boost.org/doc/libs/1_47_0/libs/smart_ptr/intrusive_ptr.html
4. Спасибо за подсказку, хотя я, вероятно, не смогу ее использовать, всегда приятно видеть, как Boost решил ее 😉
Ответ №1:
Лучше всего думать о вашем постоянном интеллектуальном указателе как о постоянном указателе на непостоянный объект. Это похоже на:
int * const int_ptr;
Если вам нужен указатель на постоянный объект:
Pointer<const int> const_int_smart_ptr;
что в основном эквивалентно:
const int *const_int_ptr;
Комментарии:
1. итак, вы бы выбрали версию, которую я написал в вопросе?
2. да — нельзя сделать так, чтобы указатель на константу указывал на что-то другое (например, operator= не должен быть разрешен для указателя const), но значение того, на что оно указывает, должно быть изменяемым.
Ответ №2:
Объект, обозначенный с помощью pointee
, похоже, не принадлежит Pointer
, поэтому я не вижу причин предполагать, что вызов const
функции Pointer
вернет a T const*
, а не a T*
. (Если бы указанный объект был концептуально частью Pointer
, конечно, проблема была бы другой.)
Комментарии:
1. » Если указанный объект концептуально был частью указателя «, тогда класс больше не является «указателем», а скорее контейнером.