有關在C++類中有條件地定義成員函數的建議是什麼? (這個問題集中在限制DLL中某些類的外部暴露 - 特別是當這些類作爲參數傳入時)。顯然,這不是你想要對數據成員做的事情,但功能應該沒問題吧?有條件成員函數
例如:
class A
{
public:
void func1();
#ifdef _CONDITION_
void func2(B b);
#endif
};
編輯: 新增公共修改,以避免混淆例子。
有關在C++類中有條件地定義成員函數的建議是什麼? (這個問題集中在限制DLL中某些類的外部暴露 - 特別是當這些類作爲參數傳入時)。顯然,這不是你想要對數據成員做的事情,但功能應該沒問題吧?有條件成員函數
例如:
class A
{
public:
void func1();
#ifdef _CONDITION_
void func2(B b);
#endif
};
編輯: 新增公共修改,以避免混淆例子。
通常,如果您不想公開某個導出類的某些部分,那麼您應該考慮不公開該類的選項,而是提供一個類來繼承的抽象接口。
例如。
class AbstractExportedInterface
{
public:
virtual void do_stuff() = 0;
};
class HasStuffIDontWantToExport : public AbstractExportedInterface
{
public:
void do_stuff();
void do_other_stuff_that_i_dont_export();
};
那麼你會操作您所提供HasStuffIDontWantToExport *的DLL用戶的假設,他們只有頭的AbstractExportedInterface。
編輯:迴應的第一個評論
如果您希望您的DLL的客戶端能夠以某種方式使用某些類型的(第三方或其他方式),但你不希望他們有充分的訪問這些類型,並且您不具有使用直接繼承層次來創建抽象接口的靈活性。您可能可以使用pimpl模式爲您希望客戶端限制使用的每種類型創建代理接口?
例如。
class ExportedAbstractProxyObject
{
public:
virtual void do_stuff() = 0;
};
#include <3rdPartyType.h>
class ProxyObject
{
public:
void do_stuff() { pimpl_.actually_do_stuff(); }
private:
3rdPartyType pimpl_;
};
class ExportedAbstractProxyOtherObject
{
public:
virtual void do_stuff_with_thing(ExportedAbstractProxyObject* thing) = 0;
};
class ProxyOtherObject
{
public:
void do_stuff_with_thing(ExportedAbstractProxyObject* thing) { thing->do_stuff(); }
};
,那麼你可以愉快地導出任何你喜歡的界面,並且完全隱藏你的DLL中實現和第三方類型。缺點是你顯然必須創建所有這些代理對象接口。
我喜歡繼承方法,但它並不總是你控制的東西。例如,當創建的DLL鏈接到由第三方創建的靜態函數庫時。 – Nicholas 2011-04-16 02:50:28
不完全確定你在問什麼,但如果成員函數是爲了私人的類使用'私人:'關鍵字,使他們私人。
如果相反,它們的目的是爲其他類在類所在模塊的上下文中使用,但不希望外部實體知道它們,請將它們公諸於衆,但從「接口」派生類'基類,並將該接口基類暴露給外部實體。
嗯,但不幸的是,'private'關鍵字並沒有阻止應用程序在編譯時從'需要'成員函數參數的完整定義鏈接到DLL。同樣使用'private'關鍵字限制瞭如何在數據包內使用該成員函數。 – Nicholas 2011-04-16 02:53:00
這種事情一般使用public
/protected
/private
聲明,並可能friend
S,而不是預處理條件下進行。但是在一個我寫過的程序中,將一些特定的函數聲明爲private或protected(因爲需要訪問它們的獨立函數的數量)是一個問題,我在前綴僞私有函數帶有下劃線的名稱(以及明確解釋原因的明確意見),以向讀者明確說明這些功能不適合一般用途。
是的,但有了下劃線,您仍然必須定義這些函數中使用的類型。因此,必須向DLL的用戶提供更多的頭文件或轉發聲明。我真的只想提供說2頭文件,而不是60. – Nicholas 2011-04-16 03:02:28
你說你想阻止某些類的可見性,但是你的例子只隱藏了一個方法。
如果一個類不構成DLL的「公共」接口的一部分,則不需要發佈標頭。例如:
// foo.h
class Bar;
class Foo
{
private Bar* _bar;
...
}
這裏「Bar」是實現的一部分,所以不需要發送它的頭文件。如果Bar僅由Foo使用,您也可以在Foo的private/protected範圍內定義它。
你能否詳細說明你爲什麼要這樣做? #indef(預處理器)是一個編譯前的東西,所以你不能用它來使成員函數在某些調用中出現,而不是在其他調用中出現。 – seand 2011-04-16 02:24:34
使用C++中的共享庫(DLL)時,通常還包含在庫中編譯的類的頭文件。在這種情況下,我不希望使用DLL的軟件看到這些頭文件中引用的一些類。 – Nicholas 2011-04-16 02:28:36
oic;你正在創建不同風格的頭文件,一個用於內部使用,另一個用於外部接口?這聽起來像你的技術會很好。如果這與您的需求類似,我已經看到#if控制是否像__declspec(dllexport)這樣的東西被髮射的情況。 – seand 2011-04-16 02:32:53