boost::shared_ptr< const type >
От: Ignoramus  
Дата: 05.12.05 11:15
Оценка:
Использую тип

typedef boost::shared_ptr< type > type_shared;


Только сейчас заметил, что когда я пишу const type_shared или const type_shared&, то констатнтым является оболочка смартпойнтера, но не указатель, который она хранит.

Соответственно, решил, что следует определить два типа:

typedef boost::shared_ptr< type > type_shared;
typedef boost::shared_ptr< const type > type_shared_const;


Вопросы:

1) (глупый) Так все и делают?

2) Если у меня есть type_shared, а в функцию нужно передать type_shared_const, что при этом происходит? Неявное конструирование type_shared_const из type_shared? Дает ли это какой-то оверхед в runtime, или все разрешается в compile time?

Спасибо.
Re: boost::shared_ptr< const type >
От: ArtDenis Россия  
Дата: 05.12.05 11:23
Оценка:
I> Только сейчас заметил, что когда я пишу const type_shared или const
I> type_shared&, то констатнтым является оболочка смартпойнтера, но не
I> указатель, который она хранит.
Всё правильно. Когда ты вызываешь operator -> для смартпоинтера, тебе возвращается константный объект, у которого ты можешь вызывть лишь константные ф-ции. Это поведение соответствует обычному указателю на константный объект.

I> Соответственно, решил, что следует определить два типа:

Зачем?
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: boost::shared_ptr< const type >
От: Ignoramus  
Дата: 05.12.05 11:29
Оценка:
Здравствуйте, ArtDenis, Вы писали:

I>> Только сейчас заметил, что когда я пишу const type_shared или const

I>> type_shared&, то констатнтым является оболочка смартпойнтера, но не
I>> указатель, который она хранит.
AD>Всё правильно. Когда ты вызываешь operator -> для смартпоинтера, тебе возвращается константный объект, у которого ты можешь вызывть лишь константные ф-ции. Это поведение соответствует обычному указателю на константный объект.

I>> Соответственно, решил, что следует определить два типа:

AD>Зачем?

Как это зачем? Чтобы пользоваться фичей "const" компилятора С++.
Re[2]: boost::shared_ptr< const type >
От: Ignoramus  
Дата: 05.12.05 11:32
Оценка:
Здравствуйте, ArtDenis, Вы писали:

I>> Только сейчас заметил, что когда я пишу const type_shared или const

I>> type_shared&, то констатнтым является оболочка смартпойнтера, но не
I>> указатель, который она хранит.
AD>Всё правильно. Когда ты вызываешь operator -> для смартпоинтера, тебе возвращается константный объект, у которого ты можешь вызывть лишь константные ф-ции. Это поведение соответствует обычному указателю на константный объект.

Разве?
Re[3]: boost::shared_ptr< const type >
От: ArtDenis Россия  
Дата: 05.12.05 11:42
Оценка:
I> Разве?

Ошибся. Посыпаю голову пеплом
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: boost::shared_ptr< const type >
От: ArtDenis Россия  
Дата: 05.12.05 12:55
Оценка:
Здравствуйте, ArtDenis, Вы писали:

I>> Разве?


AD>Ошибся. Посыпаю голову пеплом


А вообще конечно полдянка получается. От константного умного указателя ожидаешь увидеть аналог обычного указателя на константный объект. А он тебе раз — подсовывает неконстантный...
... << RSDN@Home 1.1.4 stable rev. 510>>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re: boost::shared_ptr< const type >
От: Кодт Россия  
Дата: 05.12.05 13:06
Оценка:
Здравствуйте, Ignoramus, Вы писали:

Вообще-то большинство умных указателей соблюдают ту же семантику константности (а именно: shallow constness), что и глупый указатель. То есть, константность указателя и указуемого — ортогональны.

shared_ptr<T> принимает (в конструктор и оператор присваивания) любые shared_ptr<Y>, такие, что Y* можно неявно привести к T*
Поскольку T const* приводится к T*, то проблем не возникнет.

А если ты хочешь сделать deep constness — то изволь ручками (может быть, как обёртку над shared_ptr).
Вот только зачем она тебе нужна? Скажем, когда некоторый объект отдаёт наружу свои данные (накладывая собственную константность, естественно) — то достаточно написать пару get-функций.
class MyObject
{
  shared_ptr<MyProperty> p;
  MyProperty* q; // по контрасту
public:
  shared_ptr<MyProperty>       get_p()       { return p; }
  shared_ptr<MyProperty const> get_p() const { return p; }

  MyProperty      * get_q()       { return q; }
  MyProperty const* get_q() const { return q; }

  // а вообще, стоит ли отдавать именно указатель?
  MyProperty      & r()       { return *p; }
  MyProperty const& r() const { return *p; }
  bool exist_r() const { return p != NULL; }
};
Перекуём баги на фичи!
Re[2]: boost::shared_ptr< const type >
От: Ignoramus  
Дата: 05.12.05 14:13
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Ignoramus, Вы писали:


К>Вообще-то большинство умных указателей соблюдают ту же семантику константности (а именно: shallow constness), что и глупый указатель. То есть, константность указателя и указуемого — ортогональны.


К>shared_ptr<T> принимает (в конструктор и оператор присваивания) любые shared_ptr<Y>, такие, что Y* можно неявно привести к T*

К>Поскольку T const* приводится к T*, то проблем не возникнет.

А Вы случайно не путаете запись const T* и T* const? Первое означает константный объект, второе — константный указатель. Это мое замечание касается только формы записи, со смыслом вроде путаницы нет

К>А если ты хочешь сделать deep constness — то изволь ручками (может быть, как обёртку над shared_ptr).


А чем плох вариант, который я предложил? boost::shared_ptr< const type > ?

К>Вот только зачем она тебе нужна?


Я тоже задал себе этот вопрос — а зачем, действительно? Ответ такой: когда нужно не просто получить доступ к внутренним данным объекта (как в Вашем примере), а выдать наружу созданный объект (как в паттерне Builder), обернутый, естественно, в смарт-поинтер. Так вот, бывают ситуации, когда созданный объект должен быть const. Это можно себе представить (не является ли это плохим дизайном)? Думаю да, поправьте меня если я ошибаюсь.

К>Скажем, когда некоторый объект отдаёт наружу свои данные (накладывая собственную константность, естественно) — то достаточно написать пару get-функций.


А что делать, если в интерфейсе объекта есть также set(put)-функции? Если передавать объект без const, то клиент сможет их вызывать, а хотелось бы иметь возможность это запретить, когда нужно.
Re[5]: boost::shared_ptr< const type >
От: VoidEx  
Дата: 05.12.05 14:57
Оценка: +1
Здравствуйте, ArtDenis, Вы писали:

AD>Здравствуйте, ArtDenis, Вы писали:


I>>> Разве?


AD>>Ошибся. Посыпаю голову пеплом


AD>А вообще конечно полдянка получается. От константного умного указателя ожидаешь увидеть аналог обычного указателя на константный объект. А он тебе раз — подсовывает неконстантный...

Да никакой подлянки:
type const * ~ smart_ptr<type const> — указатель на константу
type * const ~ smart_ptr<type> const — константный указатель
Так что всё логично
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.