-
May 19th, 2005, 11:55 AM
#1
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
-
May 19th, 2005, 03:22 PM
#2
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
-
May 20th, 2005, 04:41 AM
#3
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.
-
May 20th, 2005, 05:05 AM
#4
Re: Changable pointer
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
-
May 20th, 2005, 06:09 AM
#5
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|