Inner Class (Inner Class) purpose
- Multiple sets of interfaces can be implemented without multiple inheritance, and can be converted naturally (up-casting).
- Provides multiple implementations of the same interface under a single abstraction.
Alias Motive
The virtual function signatures provided by the two independent class libraries through different interfaces may conflict, and if you need to implement both functions at this point, problems will occur. Examples are as follows:
Class Base1// from the moon{ Public:Virtual int Open(int) =0;/ * Virtual * /~base1 () {}///Do not allow polymorphic destructors};class Base2/// from Jupiter{ Public:Virtual int Open(int) =0;/ * Virtual * /~base2 () {}///Do not allow polymorphic destructors};class Derived: PublicBASE1, Publicbase2{ Public:Virtual int Open(inti) {//Where exactly does wow! come from? return 0; }/ * Virtual * /~derived () {}};
The internal class idiom is used to solve this problem.
Solutions and examples
Still the above example, two base classes do not have to be modified, instead implement subclasses as follows:
#include <iostream>Class Base1// from the moon{ Public:Virtual int Open(int) =0;/ * Virtual * /~base1 () {}///Do not allow polymorphic destructors};class Base2/// from Jupiter{ Public:Virtual int Open(int) =0;/ * Virtual * /~base2 () {}///Do not allow polymorphic destructors};class Derived//Note No inheritance{Class Base1_impl; Friend class Base1_impl;//Note statement friendClass Base1_impl: PublicBASE1//Note is public inheritance { Public:Base1_impl(derived* P):Parent_(p) {}intOpen ()Override{returnParent_->base1_open (); }Private: derived* Parent_; } base1_obj;//Note member variables.Class Base2_impl; Friend class Base2_impl;//Note statement friendClass Base2_impl: PublicBASE2//Public Inheritance { Public:Base2_impl(derived* P):Parent_(p) {}intOpen ()Override{returnParent_->base2_open (); }Private: derived* Parent_; } base2_obj;//Member variables intBase1_open () {return 111; }// Implementation intBase2_open () {return 222; }// Implementation Public:Derived() :Base1_obj( This),Base2_obj( This) {}operatorbase1& () {returnBase1_obj; }// go to base1& operatorbase2& () {returnBase2_obj; }// go to base2&};/// class DerivedintBase1_open (base1& B1) {returnB1.open (); }intBase2_open (base2& B2) {returnB2.open (); }intMainvoid) {Derived D; Std::cout << Base1_open (d) << Std::endl;//Like upcasting in inheritance.Std::cout << Base2_open (d) << Std::endl;//Like upcasting in inheritance.}
An accompanying class diagram is easy to understand:
The class derived here is not a subclass, but instead implements different interfaces through the internal two nested classes and bridges back to the two implemented functions that you define: Base1_open and Base2_open. The two nested classes do not share a secondary relationship, and the two conversion operators provided by the derived class enable derived to be converted to any base class. The other two inner class objects are also exempt from the additional lifecycle management, whose lifecycles are consistent with the derived object.
Known applications
:
The concept of the Inner class comes from Java, which is characterized by the ability of nested classes to use the private member variables and member functions of the outer class in a friend's way to support stronger interactions. And usually this inner class needs to be private.
Take the HTTP cache for the Chromium network module as an example:
This is a simple example and does not have multiple inheritance. More emphasis is placed on the OO nature of encapsulation and information hiding (Httpcache::transaction is a private class within HttpCache).
The relevant idiomatic method
- Interface Class
- Capability Query
Reference
- Thinking in C + + Vol 2-practical programming-by Bruce Eckel.
[Ood-more C + + idioms] Inner class (Inner Class)