• Create Account

### #ActualMatias Goldberg

Posted 19 December 2012 - 09:39 PM

IDeviceB *device = static_cast<IDeviceB *>(matching_device);


I think this is a bad idea and I want to avoid it. After doing a little more research, I found the visitor pattern which seems to do what I want. A compile time check is done and there's no need to record additional information about the type of a particular object. I just need to see if I can get it to work. (Yes, I am learning C++.)

The visitor pattern should do what you want.

However, again. Why would you downcast to IDeviceB?
The typical OOP approach is that you should do:
device->doYourThing();

//Declarations...
class IDevice
{
virtual void doYourThing() {} //You may want it to be pure virtual, like this:
//virtual void doYourThing() = 0; //->Pure virtual version, derived class *must* implement it.
}

class IDeviceB : IDevice
{
virtual void doYourThing() { /* Do that X something */}
}

Sure, if you are picky about performance, virtuals aren't free (but neither is the visitor pattern). But if you're still learning C++, then that's a topic for another day (when you feel you can handle it, google "data oriented design")

Finally there are rare cases (they're the exception!!!) where you may want to downcast. Particularly, I use a similar method to yours (use getType) and before the static_cast I also write "assert( dynamic_cast<IDeviceB>*myDevice )" just to double check I didn't make a mistake in getType.
But this isn't considered good practice, just last resort medicine.

By design virtuals should avoid 98% the need to downcast. While another 1.5% can be handled by storing those derived types separately so you never need to downcast. And that last 0.5% is the one you didn't see when you were planning, and may force you to choose between downcasting or refactor.

But don't overdo virtuals, in x86 they're very cheap, but if you're working for phones & consoles, they can get expensive (i.e. don't make a function virtual "just in case")

### #1Matias Goldberg

Posted 19 December 2012 - 09:37 PM

IDeviceB *device = static_cast<IDeviceB *>(matching_device);


I think this is a bad idea and I want to avoid it. After doing a little more research, I found the visitor pattern which seems to do what I want. A compile time check is done and there's no need to record additional information about the type of a particular object. I just need to see if I can get it to work. (Yes, I am learning C++.)

The visitor pattern should do what you want.

However, again. Why would you downcast to IDeviceB?
The typical OOP approach is that you should do:
device->doYourThing();

//Declarations...
class IDevice
{
virtual void doYourThing() {} //You may want it to be pure virtual, like this:
//virtual void doYourThing() = 0; //->Pure virtual version, derived class *must* implement it.
}

class IDeviceB : IDevice
{
virtual void doYourThing() { /* Do that X something */}
}

Sure, if you are picky about performance, virtuals aren't free (but neither is the visitor pattern). But if you're still learning C++, then that's a topic for another day (when you feel you can handle it, google "data oriented design")

Finally there are rare cases (they're the exception!!!) where you may want to downcast. Particularly, I use a similar method to yours (use getType) and before the static_cast I also write "assert( dynamic_cast<IDeviceB>*myDevice )" just to double check I didn't make a mistake in getType.
But this isn't considered good practice, just last resort medicine.

By design virtuals should avoid 98% the need to downcast. While another 1.5% can be handled by storing those derived types separately so you never need to downcast. And that 0.5% is the one you didn't see when you were planning, and may force you to choose between downcasting or refactor.

But don't overdo virtuals, in x86 they're very cheap, but if you're working on phones & consoles, they get expensive (i.e. don't make a function virtual "just in case")

PARTNERS