我是否必須將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_
。
我認爲''unique_ptr''更適合舉行pimpl。 – Arvid