2012-02-07 127 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似乎說它是。