2016-03-01 20 views
1

我想從DLL中導出類。它使用平普爾成語等:從DLL中導出正向聲明的類

#ifdef THING_EXPORT 
#define THING_API __declspec(dllexport) 
#else 
#define THING_API __declspec(dllimport) 
#endif 

class thing_impl; 

class THING_API thing 
{ 
public: 
    ... 
private: 
    thing_impl* pimpl_; 
}; 

thing_impl構造或析構函數(或任何方法)將不會被該DLL的可用的外部。我必須在thing_impl前面放置THING_API嗎?

回答

1

我是否必須將THING_API放在前面聲明的名稱thing_impl的前面?

這取決於,但考慮到pimpl成語的性質,不,你不需要導出它。

對於整個項目,您可能會收到有關它的警告和錯誤信息,these can be silenced或將其限制在成員變量的範圍內(如下所示);

class thing_impl; 

class THING_API thing 
{ 
public: 
    ... 
private: 
    #pragma warning(push) 
    #pragma warning(disable: 4251) 
    thing_impl* pimpl_; 
    #pragma warning(pop) 
}; 

在實施中考慮的其他因素是聲明的主要thing類裏面的「平普爾」實現類thing_impl爲私有,進一步限制了潛在的訪問。

class THING_API thing 
{ 
public: 
    thing(const thing&); 
    thing& operator=(const thing&); 
    thing(thing&&); // if needed 
    thing& operator=(thing&&); // if needed 
    ~thing(); 
    ... 
private: 
    class thing_impl; 
    #pragma warning(push) 
    #pragma warning(disable: 4251) 
    thing_impl* pimpl_; 
    #pragma warning(pop) 
}; 

有一點要注意是從一個DLL導出一個類時,整個班級將被導出,所以要確保適當的拷貝構造函數,拷貝賦值運算符和析構函數有(如上)並實施(如果需要,還可以增加移動內容)。如果它們不在那裏,編譯器會生成它們,並且由於使用pimpl_成員,它們很可能不會正確。爲此,您還可以考慮使用std::shared_ptr來協助管理pimpl_

+0

我認爲''unique_ptr''更適合舉行pimpl。 – Arvid