CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    May 2000
    Location
    Germany
    Posts
    369

    Changable pointer

    Hello!
    My application have to handle 3 kind of classes while runtime.... I am lookig for a solution that simplifies the following code...

    Code:
    IBaseFilter *rendererBasePtr = ....;
    PtrType type = VR; //possible other types VMR7 VMR9
    
    if( type == VR )
       dynamic_cast<IVideoRenderer*>(rendererBasePtr)->function1();
    else if( type = VMR7 )
       dynamic_cast<IVideoRenderer7*>(rendererBasePtr)->function2();
    else if( type = VMR7 )
       dynamic_cast<IVideoRenderer9*>(rendererBasePtr)->function3();
    I don`t need a polymorphic solution with a base class. The problem is that I have no access to to framework i am using and the types have only the IBaseFilter in common. But I don't want to call the methods of the base class!!!
    So I am looking for a template/union/... solution that simplifies the code above and let me access the correct interfaces transparently.

    Thanks in advance

  2. #2
    Join Date
    Feb 2002
    Posts
    4,640

    Re: Changable pointer

    Well, if 'IBaseFilter' is indeed an interface (or purely virtual base class), then the functions you are calling should be virtual in the base class. If that is correct, then you can do:
    Code:
    switch(type)
    {
      case VR:
        rendererBasePtr->function1();
        break;
      case VMR7:
        rendererBasePtr->function2();
        break;
      case VMR9:
        rendererBasePtr->function3();
        break;
    }
    If any or all of the functions are not virtual, then you really have no choice but to cast the interface (as you're doing). Of course, you can add the casting to the switch stmt I have above.

    Viggy

  3. #3
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Changable pointer

    It looks like you do need polymorphism, and I addressed this in a different post with regard to adapters.

    Ideally you would not need to look up type then cast, but would call a single method in your base class, thus:

    Code:
    rendererBasePtr->callFunction();
    Now the adapters could work as follows:

    Code:
    class FilterAdapterBase
    {
    public:
       virtual void callFunction() /*const ?*/= 0;
    };
    
    class FilterAdapterVR : public FilterAdapterBase
    {
      IVideoRenderer * m_pImpl;
    public:
       void callFunction() { m_pImpl->function1(); }
    };
    
    class FilterAdapterVMR7 : public FilterAdapterBase
    {
      IVideoRenderer7 * m_pImpl;
    public:
       void callFunction() { m_pImpl->function2(); }
    };
    
    class FilterAdapterVMR9 : public FilterAdapterBase
    {
      IVideoRenderer9 * m_pImpl;
    public:
       void callFunction() { m_pImpl->function3(); }
    };
    That's just an illustration to start you on your way. I'd need to see more code and more information to know exactly what you need.

  4. #4
    Join Date
    Oct 2002
    Location
    Germany
    Posts
    6,205

    Re: Changable pointer

    Quote Originally Posted by kakalake
    Code:
         IBaseFilter *rendererBasePtr = ....;
         PtrType type = VR; //possible other types VMR7 VMR9
         ...
    Do you want to avoid dynamic casting for performance reasons?

    What you can do is store the type in the base class.
    This type should be set by the derived class constructors.

    Then, you can cast statically like this -
    Code:
    if( rendererBasePtr->type == VR )
           static_cast<IVideoRenderer*>(rendererBasePtr)->function1();
        else if( rendererBasePtr->type = VMR7 )
           static_cast<IVideoRenderer7*>(rendererBasePtr)->function2();
        ...
    OR do a C-Style cast like this:
    Code:
    if( rendererBasePtr->type == VR )
      ((IVideoRenderer*)rendererBasePtr)->function1();
      else if( rendererBasePtr->type = VMR7 )
      ((IVideoRenderer7*)rendererBasePtr)->function2();
          ...
    This way you will do away with the performane overheads that come with dynamic casting - if they matter to you.

    In the code that you posted, checking for type was superfluous as you could have checked the result of the dynamic_cast operator instead.
    Like this:
    Code:
    IVideoRenderer7* pVR7 = dynamic_cast<IVideoRenderer7*>(rendererBasePtr);
       if (pVR7)
          pVR7->function1();
       else
        ... // It is some other sub-class pointer

  5. #5
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: Changable pointer

    If you use a v-table you don't need dynamic casting at all though.

    And it is more extensible (you don't need to change your code to add in another case, you can simply make additional adapters).

    By the way, this (below) is a general rule whenever you have a switch statement, and call a different function dependent on the case:

    - See if you can create a table of handlers. The use the value of the "switch" to see which handler to call. If not found in your table, then you either call a default handler (as would be your code in "default"), or do nothing (if that's what you want to do) or throw an exception / assert. (Assert if it's caused by a programming error, exception if caused by a user error).

    That rule applies when the value of the "switch" is determined by run-time information. In your case though, you were using a "type-id" within your class to determine what to do, which suggests you don't need a table at all, but a simple polymorphism.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured