The Inner Class Idiom

Usd in case where we must upcast to more than one type, but we need to provide different implementations of the same base type.

Example:

#include <iostream>
#include <string>
 
using namespace std;
 
class Poingable
{
public:
    virtual void poing() = 0;
};
 
void callPoing(Poingable& p)
{
    p.poing();
}
 
class Bingable
{
public:
    virtual void bing() = 0;
};
 
void callBing(Bingable &b)
{
    b.bing();
}
 
class Outer
{
    string name;
 
    //define one inner class
    //this means that somewhere there is a nested class of the name Inner1.
    //this allows the friend declaration that follows.
    class Inner1;
    friend class Outer::Inner1;
 
    /*
     * The inner class definitions are private and the client code
     * doesn't have any access to details of the implementation.
     */
    class Inner1 : public Poingable
    {
        Outer *parent; //it keeps a pointer to the Outer which created it 
                        // this pointer must be initialized in the constructor.
    public:
        Inner1(Outer *p) : parent(p) {}
        void poing()
        {
            cout << "poing called for " << parent->name << endl; // accesses data in the outer class object
        }
    }inner1;
 
    //define a second inner class
    class Inner2;
    friend class Outer::Inner2;
    class Inner2 : public Bingable 
    {
        Outer *parent;
    public:
        Inner2(Outer *p) : parent(p) {}
        void bing()
        {
            cout << "bing called for " << parent->name << endl;
        }
    }inner2;
 
public:
    /*
    * The Outer constructor contains some private data (name) and 
    * it wants to provide both a Poingable interface and a Bingable interface
    * so it can be used with callPoing() and callBing()
    */
    Outer(const string& nm) : name (nm), inner1(this), inner2(this) {}
    /*
     * These two operators only return a reference to the upcast interface
     * not to the object that implements it.
     */
    operator Poingable&() { return inner1;}
    operator Bingable&() { return inner2;}
};
 
int main()
{
    Outer x("Ping Pong");
    callPoing(x);
    callBing(x);
 
    getchar();
 
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.