Russian Qt Forum
Май 01, 2024, 20:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: implicit sharing  (Прочитано 8136 раз)
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« : Сентябрь 28, 2010, 09:29 »

В этом посте не буду оригинален, я попытался себе упростить написание классов со скрытым разделением ресурсов (implicit sharing). QT у себя внутри использует этот подход во многих классах, но почему-то я не нашел у них никаких вспомогательных классов для этого, ну если не считать QAtomicInt Улыбающийся

Вот что у меня получилось:
Код
C++ (Qt)
#pragma once
 
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
 
template <class Body>
class implicit_sharing
{
public:
   implicit_sharing()
   : body_(boost::make_shared<Body>())
   {
   }
 
   /*! Call this from all non const methods. */
   void detach()
   {
       if (body_.unique())
           return;
       boost::shared_ptr<Body> old = body_;
       body_ = boost::make_shared<Body>(*(body_.get()));
   }
 
   /*! Access to shared body. */
   inline Body* operator->() const
   {
       return body_.get();
   }
 
   inline Body* operator->()
   {
       detach();
       return body_.get();
   }
 
private:
   boost::shared_ptr<Body> body_;
};
 

Пример использования:
Код
C++ (Qt)
class my_data
{
public:
   int val() const {return d->val;}
 
   void set_val(int val)
   {
       d->val = val;
   }
 
private:
   struct impl
   {
       int val;
   };
   implicit_sharing<impl> d;
};
 

В этом классе я углядел пока две проблемы:
  • проблемы с многопоточностью
  • отсутствие возможности передать в конструктор impl параметры из конструктора класса-носителя

Вместо boost::shared_ptr можно, конечно же, использовать QSharedPtr, правда с потерей оптимальности, т.к. нет в Qt make_shared.

Буду рад если это кому то поможет и вдвойне рад если кто-то поможет тут устранить проблемы Подмигивающий
« Последнее редактирование: Ноябрь 14, 2010, 01:56 от navrocky » Записан

Гугль в помощь
maxxant
Гость
« Ответ #1 : Сентябрь 28, 2010, 17:59 »

не понял.
всё есть и с примерами:

http://doc.qt.nokia.com/4.6/implicit-sharing.html
http://doc.qt.nokia.com/4.6/qshareddatapointer.html

Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #2 : Сентябрь 28, 2010, 18:03 »

да, действительно не углядел... одним велосипедом больше стало Веселый

ЗЫЖ хотя в моем варианте меньше буков писать, для себя я использую эту реализацию вместо QSharedDataPointer..
« Последнее редактирование: Ноябрь 14, 2010, 01:58 от navrocky » Записан

Гугль в помощь
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #3 : Ноябрь 02, 2014, 18:07 »

Всё таки моя реализация лучше, чем QSharedData + QSharedDataPointer. Только сейчас, попробовав QSharedData  в работе, я это понял  Улыбающийся

Когда используешь QSharedDataPointer в наследнике QObject, то необходимо определить структуру Data полностью в хедере, т.к. метакомпилятор что-то там досоздает и возникает ошибка компиляции.

Код
C++ (Qt)
class MyObject : public QObject
{
   Q_OBJECT
public:
   MyObject();
private:
   struct Data;
   QSharedDataPointer<Data> d;
};
 

Код:
/usr/include/qt5/QtCore/qshareddata.h:87:45: error: invalid use of incomplete type 'struct MyObject::Data'
     inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }

А часто хочется скрыть реализацию, упрятав её с внутренними зависимостями в cpp файл.

Более того:

1) с QSharedDataPointer надо писать больше буков. Надо создать Data во всех конструкторах, в моём случае это не надо делать, создание происходит автоматически.

2) не надо наследовать Data от QSharedData

PS. Если использовать c++11, то зависимость от буста можно выкинуть.
Записан

Гугль в помощь
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #4 : Ноябрь 06, 2014, 13:08 »

Код:
/usr/include/qt5/QtCore/qshareddata.h:87:45: error: invalid use of incomplete type 'struct MyObject::Data'
     inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }

Вынесите деструктор в цпп и будет счастье
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #5 : Ноябрь 12, 2014, 18:55 »

Код:
/usr/include/qt5/QtCore/qshareddata.h:87:45: error: invalid use of incomplete type 'struct MyObject::Data'
     inline ~QSharedDataPointer() { if (d && !d->ref.deref()) delete d; }

Вынесите деструктор в цпп и будет счастье

Деструктор QSharedDataPointer, вы шутите?
Записан

Гугль в помощь
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.104 секунд. Запросов: 22.