C++ 相較於 Java, 可以直接在 stack 上配置物件, 而不是全部都是 pointer (reference), 因此, C++ 要求在 include class 時, 得知道該 class 的所有 member field, 才知道要配多大的空間。這帶來一個問題, 即使 header 檔改的是 private member field/method, 全部有引入該 header 的檔案都要重編, 專案變大後, 是頗為痛苦的事。
解決這問題有幾種作法, 基本精神就是架空 class, 讓它不會有更動 private member field/method 的機會。書上提出兩個作法: 使用 handle class, 或稱 pimpl idiom (pimpl: pointer to implementation) 使用 interface class (abstract base class)
以 class Person 為例, 第一個作法是在 Person 裡加上一個 private member: PersonImpl *pImpl, 然後所有方法都透過它執行, 例如:std:string Person::name() const
{
return pImpl->name();
}
interface class 則是全部方法都宣告為 virtual 並不提供實作 (別忘了提供 virtual destructor), 這樣 Person 不能初始化, 效果如同 Java 的 interface (不過有彈性可提供 method 和 field), 像這樣:class Person
{
public:
virtual ~Person();
virtual std::string name() const = 0;
...
}
然後再寫個 class RealPerson 繼承 Person, 提供真正的實作。
於是, 不管用 handle class 或 interface class, 只要沒有加減 interface 的 method, 相依 Person 的程式都不需重編, 邏輯上也做到令用戶端程式相依於介面而非實作, 達到良好的封裝效果。當然, 相對於直接實作 class Person, 兩者…