2012-02-07 125 views
3

我有一个类,有一些数据成员,我想从调用者隐藏(因为包括他们的类型的头显着增加了编译时间,它会要求每个项目使用这个类来添加一个额外的路径到他们的包含路径)。私人(隐藏)QSharedData

本课程使用QSharedDataPointer来存储这些数据。这样可以通过使用默认的拷贝构造函数来复制它。

这个类的基本结构是:

class MyClass { 
private: 
    QSharedDataPointer<MySharedClassData> m_data; 
}; 

有任何花哨的技巧来做到这一点没有定义MySharedClassData(从QSharedData继承)在相同的头文件?或者还有其他隐藏数据字段的好方法吗?

我已经尝试了MySharedClassData的前向声明,但这并不奏效(尽管m_dataprivate)。

我目前唯一可以解决的问题是将m_data声明为QSharedDataPointer<QSharedData>,但随后我需要在每次访问数据成员时都强制转换数据成员。有更好的解决方案吗?

+1

是[Pimpl](http://en.wikipedia.org/wiki/Opaque_pointer)在这种情况下我能想到的一个成语? – maverik 2012-02-07 12:27:32

+0

@maverik:是的。 “QSharedDataPointer类表示一个'impl'共享对象的'p'ointer。” – MSalters 2012-02-07 12:35:02

+0

是的,这正是我想要做的。不幸的是,这似乎不适用于'QSharedDataPointer'。或者至少我不明白,如何做到这一点。 – 2012-02-07 12:35:13

回答

6

只要你的构造函数和析构函数没有在头文件中定义,前向声明就应该工作。下面的类编译我的电脑上:在VS. C2027: use of undefined type 'type'

#ifndef MAIN_WINDOW_HXX 
#define MAIN_WINDOW_HXX 

#include <QMainWindow> 
#include <ui_MainWindow.h> 

#include <QSharedDataPointer> 

class MySharedClassData; 

class MainWindow : public QMainWindow, private Ui_MainWindow { 
    Q_OBJECT 
public: 
    explicit MainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); 
    virtual ~MainWindow(); 

    QSharedDataPointer<MySharedClassData> m_data; 

}; 

#endif 

如果试图内联构造函数/析构函数,那么你可能会收到一个

+0

这是正确的提示。但在我的情况下,我还需要手动实现复制构造函数和赋值运算符。 – 2012-02-07 12:49:51

+0

我可以确认operator =()似乎是MSVC和其他编译器所必需的。 Clang和GCC没有它的工作。 – 2012-10-17 23:16:17

+0

我不知道我应该声明析构函数(甚至在cpp文件中的空实现)!谢谢!! – Brent81 2013-10-23 16:32:32

0

是的。没有必要的真正花哨的技巧。但是,做的所有方法需要MySharedClassData必须在定义MySharedClassData后定义。如果您将类定义移动到.cpp文件,那么方法也必须移到那里。

0

一般来说,如果您想使用带有智能指针指向前向声明的impl的pimpl惯用语(而不是手动管理impl对象),则需要带有一个非线性删除器的智能指针,如boost::shared_ptr(您应该可以使用std::unique_ptr自定义删除程序,但我没有尝试过)。

要求是您可以在不看到impl类析构函数的情况下实例化智能指针模板:例如,这排除了std::auto_ptr

我不知道QSharedDataPointer是否符合要求,但tibur似乎说它是。