Const с помощью интеллектуальных указателей в C

#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. » Если указанный объект концептуально был частью указателя «, тогда класс больше не является «указателем», а скорее контейнером.