LINUX.ORG.RU

не деструктятся шаред поинтеры

 , ,


0

3

Поясните по хардкору, почему список при деструктурировании не деструктит шаред поинтеры расположенные в нем

#include <QList>
#include <QSharedPointer>
#include <iostream>

#define LAFAFA 3
class Object {
  int data;
public:
  Object(int a) : data(a) {
    std::cout << "Object contstructed i: " << a << std::endl;
  };
  Object(const Object &cp) {
    this->data = cp.data;
    std::cout << "Object copied i: " << cp.data << std::endl;
  }
  ~Object() {
    std::cout << "Object desctructed i: " << this->data << std::endl;
  };
  void print() {
    std::cout << "Object i: " << this->data << std::endl;
  };
};

int main (int argc, char ** argv) {
  {
    std::cout << std::endl;
    std::cout << "=========== Just Objects ===================" << std::endl;
    QList<Object> one;
    for (int i=0; i < LAFAFA; i++) {
      one.append(Object(i));
    }
    std::cout << "<<<< cycle finished" << std::endl;
  };
  {
    std::cout << std::endl;
    std::cout << "============ Shared pointers ===============" << std::endl;
    QList<QSharedPointer<Object> > fuck;
    for (int i=0; i < LAFAFA; i++) {
      fuck.append(*(new QSharedPointer<Object>(new Object(i))));
    };
    std::cout << "<<<< cycle finished" << std::endl;
  };
  {
    std::cout << std::endl;
    std::cout << "============ Test Shp ======================" << std::endl;
    QSharedPointer<Object> test = QSharedPointer<Object>(new Object(10));
  }
};
вывод


=========== Just Objects ===================
Object contstructed i: 0
Object copied i: 0
Object desctructed i: 0
Object contstructed i: 1
Object copied i: 1
Object desctructed i: 1
Object contstructed i: 2
Object copied i: 2
Object desctructed i: 2
<<<< cycle finished
Object desctructed i: 2
Object desctructed i: 1
Object desctructed i: 0

============ Shared pointers ===============
Object contstructed i: 0
Object contstructed i: 1
Object contstructed i: 2
<<<< cycle finished

============ Test Shp ======================
Object contstructed i: 10
Object desctructed i: 10
В доках по QList сказано что

Destroys the list. References to the values in the list and all iterators of this list become invalid.

fuck.append(*(new QSharedPointer<Object>(new Object(i))));

Здесь в куче выделяется shared pointer, разыменовывается и его копия попадает в список (конструктор копирования!)

Список действительно вызывает деструкторы для твоих поинтеров, однако для каждого поинтера есть его копия в куче, которую ты создал.

QSharedPointer деструктит указатель если на него больше не осталось ссылок, но в твоем случае это не так.

x4DA ★★★★★ ()
Ответ на: комментарий от panter_dsd

Сто пудово, я тупанул так работает.

А кстати не сильно ли падает производительность ЦЭПЭПЭ программ при подобной передаче по ссылке, ведь выходит, что при каждом вызове append всегда вызвается конструктор копирования.

s9gf4ult ★★ ()
Ответ на: комментарий от s9gf4ult

У Кьюта практически все имплисит шаред, то есть копируются данные только при изменении онных.

panter_dsd ★★★★ ()
Ответ на: комментарий от panter_dsd

Я имею в виду как самому сделать CoW для своих классов. Вот есть у меня сейчас большое количество некоторых маленьких объектов (может быть порядка нескольких миллионов). Как сделать для них автоматический CoW

s9gf4ult ★★ ()
Ответ на: комментарий от s9gf4ult
#ifndef COWPTR_HPP
#define COWPTR_HPP
 
#include <boost/shared_ptr.hpp>
 
template <class T>
class CowPtr
{
    public:
        typedef boost::shared_ptr<T> RefPtr;
 
    private:
        RefPtr m_sp;
 
        void detach()
        {
            T* tmp = m_sp.get();
            if( !( tmp == 0 || m_sp.unique() ) ) {
                m_sp = RefPtr( new T( *tmp ) );
            }
        }
 
    public:
        CowPtr(T* t)
            :   m_sp(t)
        {}
        CowPtr(const RefPtr& refptr)
            :   m_sp(refptr)
        {}
        CowPtr(const CowPtr& cowptr)
            :   m_sp(cowptr.m_sp)
        {}
        CowPtr& operator=(const CowPtr& rhs)
        {
            m_sp = rhs.m_sp; // no need to check for self-assignment with boost::shared_ptr
            return *this;
        }
        const T& operator*() const
        {
            return *m_sp;
        }
        T& operator*()
        {
            detach();
            return *m_sp;
        }
        const T* operator->() const
        {
            return m_sp.operator->();
        }
        T* operator->()
        {
            detach();
            return m_sp.operator->();
        }
};
 
#endif
x4DA ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.