LINUX.ORG.RU

Pimpl + const'анстность методов


1

1

Набрел я в хабре на следующую статью Перевод статьи «Pimp my Pimpl», часть 2

А именно на проблемы константности методов. Обычный Pimpl

class A()
{
void some() {_a->some();}
void some() const {_a->some();}

class Impl;
Impl* _a;
}
Для обоих A::some вызовет не константный метод A::Impl::some(). Увидав предложенный в статье deep_const_ptr, Я подумал «а зачем ?» ведь в место него можно заюзать shared_ptr. И вот тут меня настигло разочарование
    T * operator-> () const // never throws
    {
        BOOST_ASSERT(px != 0);
        return px;
    }

    T * get() const // never throws
    {
        return px;
    }

единственный вопрос, ПОЧЕМУ ? почему не

    T * get() // never throws
    {
        return px;
    }

    const T * get() cnost// never throws
    {
        return px;
    }


Потому что shared_ptr имеет семантику указателя

NikolaSh
()

А в чём проблемма то?

братюня, я не понял, в чём проблема? const shared_ptr<Impl> // константный указатель shared_ptr<const Impl> // константный объект за указателем const shared_ptr<const Impl> // ну ты понел

выбирай на свой вкус.

anonymous
()
Ответ на: А в чём проблемма то? от anonymous

Не люблю я быть братюней.

Не имеет смысла в Pimpl использовать shared_ptr так как он не дает нам возможности константность нашего типа навязаться самому Impl семантикой самого языка.

class Class
{
   void some(){p->some()};
   void some() const {p->some();}

   class Private;
   shared_ptr<Private> p;
};

Class c1;
c1.some(); // не константный Class::Private::some 

const Class c2;
c2.some();   // константный Class::some()
             // НО не константный Class::Private::some 

Cupper
() автор топика
Ответ на: комментарий от Cupper

Тогда

class Class {
public:
  Class () {}
  ~Class () {}
  
  void some () { p->some(); }
  void some () const { p->some(); }
  
private:
  class Impl {
  public:
    void some () { std::cout << "non const\n"; }
    void some () const { std::cout << "const\n"; }
  };
  
  class ptr {
  public:
    ptr () { p = new Impl; }
    ~ptr () { delete p; }
    
    Impl* operator ->() { return p; }
    const Impl* operator ->() const { return const_cast<const Impl*>(p); }
    
  private:
    Impl *p;
  };
  
  ptr p;
};

[[/code]]
anonymous
()
Ответ на: комментарий от anonymous

заглянул бы хоть по ссылке, там все это есть и без всяких const_cast'ов. Вопрос то был в другом.

Cupper
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.