我有一個庫中有多個類,它們具有我希望從客戶端代碼隱藏的內部特徵。從客戶端的角度來看,每個類都是從庫類中查詢的,並且僅用作不透明指針。一個例子如下:隱藏公共接口和ODR中的成員
struct SomeSystem;
void doSomethingToSomeSystem(SomeSystem* system, Parameters params);
void doSomethingElseToSomeSystem(SomeSystem* system, Parameters params);
在實施側,SomeSystem具有多個構件,其不給調用者可見。這是所有罰款,但我真的不喜歡笨重的使用語法:
SomeSystem* system = lib->getSomeSystem();
doSomethingToSomeSystem(system, params);
doSomethingElseToSomeSystem(system, params);
另一種方法是這樣的:
struct SomeSystem;
namespace somesystem {
void doSomething(SomeSystem* system, Parameters params);
void doSomethingElse(SomeSystem* system, Parameters params);
}
隨着使用代碼:
SomeSystem* system = lib->getSomeSystem();
somesystem::doSomething(system, params);
somesystem::doSomethingElse(system, params);
我可以還使用全局方法doSomething
和doSomethingElse
,並且如果另一種類型也定義了doSomething
,則取決於函數重載。但是,在這種情況下,很難在IDE中找到SomeSystem的所有「成員」。
我很想實際使用成員函數:
struct SomeSystem {
void doSomething(Parameters params);
void doSomethingElse(Parameters params);
};
隨着使用代碼:
SomeSystem* system = lib->getSomeSystem();
system->doSomething(params);
system->doSomethingElse(params);
最後片段對我來說很好,但SomeSystem不再是一個不透明的指針 - 它實際上定義了成員。我對此有點謹慎。一個潛在的問題是一個定義規則。然而,只有不同的翻譯單位才能看到該類的「公共」定義和「私人」定義。這裏是否還有其他不良之處?如果客戶端代碼嘗試在堆棧上實例化SomeSystem或使用新的代碼,它顯然會使程序崩潰。但我願意接受這一點。也許我可以通過在公共接口中提供一個私有構造函數來解決這個問題。
另一種方法當然是用純虛擬方法定義抽象類。 但是,如果不是絕對必要的,我想避免這種開銷。
編輯:
要清楚,我想知道,如果它是合法的,有一個公共的頭,該客戶端包括包含類的不是什麼實現使用一個不同的定義(有一些成員失蹤) ,因爲客戶端從不實例化類。
公共標題:
struct SomeSystem {
void doSomething(Parameters params);
void doSomethingElse(Parameters params);
};
私人標題:
struct SomeSystem {
Member member;
void doSomething(Parameters params);
void doSomethingElse(Parameters params);
};
私人來源(包括私有頭):
void SomeSystem::doSomething(Parameters params) {
...
}
void SomeSystem::doSomethingElse(Parameters params) {
...
}
這時候我測試,但我不確定是否工作它以某種方式違反了標準。兩個標題永遠不會包含在同一個翻譯單元中。
您是否熟悉[不透明指針/ Pimpl成語](http://en.wikipedia.org/wiki/Opaque_pointer)? – 2015-03-31 16:47:23
是的,我很熟悉它,我寧願避免它。它引入了額外的內存分配並使執行復雜化。 – rasmus 2015-03-31 16:51:16
請注意,我特別是在語法糖後沒有使我的解決方案性能或複雜性更差。 – rasmus 2015-03-31 16:52:55