2010-04-08 5 views
4

Как скрыть частную реализацию (неявное совместное использование) в Qt:Могу ли я использовать QSharedData при наследовании от QObject?

У меня есть Employee.cpp следующее в моем Employee.h заголовке:

#include <QSharedData> 
#include <QString> 


class EmployeeData; 
class Employee: public QObject 
{ 
    Q_OBJECT 
    public: 
    Employee(); 
    Employee(int id, QString name); 
    Employee(const Employee &other); 
    void setId(int id); 
    void setName(QString name); 

    int id(); 
    QString name(); 

private: 
    QSharedDataPointer<EmployeeData> d; 
}; 

class EmployeeData : public QSharedData 
{ 
    public: 
    EmployeeData() : id(-1) { name.clear(); } 
    EmployeeData(const EmployeeData &other) 
     : QSharedData(other), id(other.id), name(other.name) { } 
    ~EmployeeData() { } 

    int id; 
    QString name; 
}; 

Но когда я перехожу EmployeeData к закрытой части , скажем Employee.cpp я получаю: ошибка: неправильное использование неполного типа «STRUCT EmployeeData»

Однако, если я изменю свое определение этому он отлично работает:

class Employee 
{ 
public: 
    Employee(); 
    Employee(int id, QString name); 
.. 

Таким образом, могу ли я использовать QSharedData при наследовании от QObject?

ответ

2

Thus, can I use QSharedData while inheriting from QObject ?

Вы не можете наследовать от QObject при использовании QSharedData. QSharedData использует семантику copy-on-write и вызывается detach(), чтобы создать копию данных, когда она больше не используется совместно. Чтобы сделать копию, необходим конструктор-копир, который QObject не поддерживает.

pimpl (или handle-body/opaque-pointer idiom) часто дает классу данных ссылку на публичную реализацию, а именно, как вы ожидаете работать с сигналами и слотами.

QSharedDataPointer обеспечивает большую часть деталей реализации, но это также весьма полезно взглянуть на Pimpl идиомы, используемый в Qt (see Q_D and friends)

+0

я не видел нигде в 'документации QSharedDataPointer', как вы могли бы хранить ссылку на публичный класс. У вас есть контроль над конструктором копирования, но когда копия сделана, ссылка на родительский объект не передается, поэтому, если класс, к которому теперь привязаны данные, знает, что вызывается 'detach()', это может Не уведомляйте данные о том, что у него новый владелец. Мысли? Предложения? Может быть, вам понадобится подкласс 'QSharedDataPointer' для поддержки такой операции? –

+0

Дарн, я хотел иметь свой торт и съесть его тоже! Моя идея состояла в том, чтобы иметь объект передачи данных (передачи) с 1) сигналами и слотами, 2) pimpl И 3) copy-on-write. Наверное, нет колоколов и свистков и живут с 2 и 3. Или есть предложения по 1 + 2 + 3 с использованием классов Qt? –

+0

Как ваши соединения будут передаваться/копироваться при копировании вашего объекта данных? Зачем вам нужны сигналы/слоты непосредственно в классе данных? –