开发者

What is the use of a C++ class containing an "implementation" and "interface" pointer to itself?

I'm studying some source codes and I'm just wonderi开发者_如何学Cng why a class (or classes) is often implemented this way:


class EventHandler
{
...
    EventDispatcher* m_Dispatcher;
    virtual bool ProcEvent( EventHandler* Sender, int Task, int Event, void* Param );
...
};

class ClassA: public EventHandler
{
...
    ClassA* m_Impl;
    ClassA* m_Iface;
...
public:
    // virtual functions
    virtual bool ProcEvent( EventHandler* Sender, int Task, int Event, void* Param );
    virtual void OnDataWritten(const PIOResult&) {;}
    ...

    // sample functions
    void SetImplement( ClassA* aImpl );
    void SetInterface( ClassA* aIface );
    ClassA* GetImplement() { return m_Impl; }
    ClassA* GetInterface() { return m_Iface; }
    bool GetData( list& aList );
};

// Implementation of some sample functions; Most of its function contain more
// or less the same format as below, with the return m_Impl->XXX having the same
// name as the function being defined (e.g. A::XXX)
bool ClassA::GetData( list< Data >& aList )
{
    if( m_Impl )
        return m_Impl->GetData( aList );
    else
        return false;
}

class ClassAFactory: public EventHandler
{
private:
    ClassAFactory* m_Impl;
    ClassAFactory* m_Iface;

protected:
    virtual ClassA* MakeTransport();

    virtual bool ProcEvent( EventHandler* Sender, int Task, int Event, void* Param );
    virtual ClassA* CreateClassA() { return 0; }

...
};

// In some member function of ClassB (ClassB inherits ClassA)

switch( status )
{
    case 1:
        GetInterface()->OnDataWritten();
    case 2:
        // ...
};


I believe it's for some design pattern but I'm not familiar with it. It could help me understand if I know what it is. Can anyone help me point out which it could be or what is the use of these classes such that it is implemented this way?

I think it's for some event handling and used together with some factory but I'm not sure.


I am afraid the names used do not have the usual meaning, so without examples of what is put in or how they are used, it's going to be difficult to guess.

There are 2 design patterns that you should check, that make heavy use of this kind of self-recursion (at class level*):

  • The Decorator Pattern
  • The Composite Pattern

And I am afraid that you are looking at something that fails to emulate either of those.

In the Decorator, the point is to add functionality. To this end you have an Interface of which derives a Concrete class and a Wrapper interface. Then various wrappers will derive of Wrapper and you can chain them:

Interface* interface = new Wrapper2( new Wrapper1 ( new Concrete() ) );

Each wrapper add some functionality, whereas here we only have perfect forwarding... so it's not a Decorator.

The Composite pattern is different. Its goal is to hide whether you treat with a collection of elements or a single element. The usual example is a tree: you can apply operations either to an entire subtree or just a leaf node if it's implemented with a Composite Pattern.

Once more, there is not such thing here.

So my best guess is that you have either a wild design (perhaps a misguided attempt to emulate a well-known pattern) or you haven't given enough information (source code) for us to figure out the role. It seems strange anyway.

*Note: by self-recursion at class level I mean that an object of class A points to another object of class A, but this does not mean (certainly) that it points to the same instance... otherwise we would have a Stack Overflow (pun intended). This not the same instance bit is certainly worth checking during the SetImplementation call: note that any cyclic reference would cause death by recursion.


I wild guess, but could it be the "pimpl idiom" you are looking for? http://www.gamedev.net/reference/articles/article1794.asp

EDIT
The expanded code sample with the implementation of GetData is definitely an example of the pimpl idiom. However that does not explain the m_Iface member. Can you provide an example of where that is used too?

EDIT2
With the added example of how m_Iface is shown it is clear i was wrong regarding the pimpl. It is a kind of decorator. The m_Impl points to the underlying object, while the m_Iface points to the outermost layer, so that an underlying object can make a call which goes through the entire chain of decorators. This example is a bit complicated as ClassA both is the interface class and the default implementation. If you would like to create a decorator to the class you will have to inherit ClassA.


This looks much more C than C++. In any object-oriented language, you would use inheritance and virtual functions to get this behaviour.

Using an internal pointer to an implementation class is perfectly fine (the pimpl idiom), but this pointer would not normally be accessible to callers. And I don't get the interface pointer at all.


I'm not sure if this is a classic example of the pimpl idiom, but if so, the point is to separate the interface (which should be stable) from the implementation details (which you should be relatively free to change).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜