[OOD-More C++ Idioms] 內部類 (Inner Class)
來源:程序員人生 發布時間:2016-02-29 16:54:00 閱讀次數:3813次
內部類 (Inner Class)
目的
-
不用通過量重繼承就能夠實現多套接口,同時可以自然地向上轉換(Up-casting)。
-
在單個抽象下提供相同接口的多個實現。
別名
動機
兩個獨立類庫通過不同的接口提供的虛函數簽名可能沖突,如果這時候需要同時實現這兩個函數就會出現問題。示例以下:
class Base1 { public: virtual int open (int) = 0; ~Base1() {} };
class Base2 { public: virtual int open (int) = 0; ~Base2() {} };
class Derived : public Base1, public Base2
{ public: virtual int open (int i)
{ return 0;
} ~Derived () {}
};
內部類慣用法就是用來解決這個問題。
解決方案及示例
依然是上面的例子,兩個基類不用修改,改用以下方式實現子類:
#include class Base1 { public: virtual int open (int) = 0; ~Base1() {} };
class Base2 { public: virtual int open (int) = 0; ~Base2() {} };
class Derived {
class Base1_Impl;
friend class Base1_Impl; class Base1_Impl : public Base1 // 注意是公共繼承
{ public: Base1_Impl(Derived* p) : parent_(p) {} int open() override { return parent_->base1_open(); } private:
Derived* parent_;
} base1_obj; class Base2_Impl;
friend class Base2_Impl; class Base2_Impl : public Base2 // 公共繼承
{ public: Base2_Impl(Derived* p) : parent_(p) {} int open() override { return parent_->base2_open(); } private:
Derived* parent_;
} base2_obj; int base1_open() { return 111; } int base2_open() { return 222; } public: Derived() : base1_obj(this), base2_obj(this) {} operator Base1&() { return base1_obj; } operator Base2&() { return base2_obj; } }; int base1_open(Base1& b1) { return b1.open(); } int base2_open(Base2& b2) { return b2.open(); } int main(void) {
Derived d;
std::cout << base1_open(d) << std::endl; std::cout << base2_open(d) << std::endl; }
附個類圖便于理解:
這里的類Derived其實不是子類,而是通過內部的兩個嵌套類實現不同的接口,再橋接回到自己定義的兩個實現的函數: base1_open及base2_open。兩個嵌套類不會同享繼隨關系,通過Derived類提供的兩個轉換操作符可以實現Derived轉換到任意的基類。另外兩個內部類對象也免去了額外的生命周期管理,它們的生命周期與Derived對象1致。
已知的利用
譯注:
Inner Class的概念來自于Java, 其本特點是嵌套類通過友元的方式可使用外部類的私有成員變量和成員函數,從而支持更強的交互。而且通常這個內部類需要是私有的。
以Chromium網絡模塊的Http Cache為例:
這是1個簡單的例子,并沒有多重繼承。更多的是強調了封裝和信息隱藏(HttpCache::Transaction是HttpCache內私有的類)的OO特性。
相干的慣用法
-
Interface Class
-
Capability Query
-
Thinking in C++ Vol 2 - Practical Programming ― by Bruce Eckel.
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈