Inheritence and usage of dynamic_cast - c++

Suppose I have 3 classes as follows (as this is an example, it will not compile!):
class Base
{
public:
Base(){}
virtual ~Base(){}
virtual void DoSomething() = 0;
virtual void DoSomethingElse() = 0;
};
class Derived1
{
public:
Derived1(){}
virtual ~Derived1(){}
virtual void DoSomething(){ ... }
virtual void DoSomethingElse(){ ... }
virtual void SpecialD1DoSomething{ ... }
};
class Derived2
{
public:
Derived2(){}
virtual ~Derived2(){}
virtual void DoSomething(){ ... }
virtual void DoSomethingElse(){ ... }
virtual void SpecialD2DoSomething{ ... }
};
I want to create an instance of Derived1 or Derived2 depending on some setting that is not available until run-time.
As I cannot determine the derived type until run-time, then do you think the following is bad practice?...
class X
{
public:
....
void GetConfigurationValue()
{
....
// Get configuration setting, I need a "Derived1"
b = new Derived1();
// Now I want to call the special DoSomething for Derived1
(dynamic_cast<Derived1*>(b))->SpecialD1DoSomething();
}
private:
Base* b;
};
I have generally read that usage of dynamic_cast is bad, but as I said, I don't know
which type to create until run-time. Please help!

Why not delay the moment at which you "throw away" some if the type information by assigning a pointer to derived to a pointer to base:
void GetConfigurationValue()
{
// ...
// Get configuration setting, I need a "Derived1"
Derived1* d1 = new Derived1();
b = d1;
// Now I want to call the special DoSomething for Derived1
d1->SpecialD1DoSomething();
}

The point of virtual functions is that once you have the right kind of object, you can call the right function without knowing which derived class this object is -- you just call the virtual function, and it does the right thing.
You only need a dynamic_cast when you have a derived class that defines something different that's not present in the base class, and you need/want to take the extra something into account.
For example:
struct Base {
virtual void do_something() {}
};
struct Derived : Base {
virtual void do_something() {} // override dosomething
virtual void do_something_else() {} // add a new function
};
Now, if you just want to call do_something(), a dynamic_cast is completely unnecessary. For example, you can have a collection of Base *, and just invoke do_something() on every one, without paying any attention to whether the object is really a Base or a Derived.
When/if you have a Base *, and you want to invoke do_something_else(), then you can use a dynamic_cast to figure out whether the object itself is really a Derived so you can invoke that.

Using dynamic_cast is not bad practice per se. It's bad practice to use it inappropriately, i.e. where it's not really needed.
It's also a bad practice to use it this way:
(dynamic_cast<Derived1*>(b))->SpecialD1DoSomething();
Reason: dynamic_cast(b) may return NULL.
When using dynamic_cast, you have to be extra careful, because it's not guaranteed, that b is actually of type Derived1 and not Derived2:
void GenericFunction(Base* p)
{
(dynamic_cast<Derived1*>(b))->SpecialD1DoSomething();
}
void InitiallyImplementedFunction()
{
Derived1 d1;
GenericFunction(&d1); // OK... But not for long.
// Especially, if implementation of GenericFunction is in another library
// with not source code available to even see its implementation
// -- just headers
}
void SomeOtherFunctionProbablyInAnotherUnitOfCompilation()
{
Derived2 d2;
GenericFunction(&d2); // oops!
}
You have to check if dynamic_cast is actually successful. There are two ways of doing it: checking it before and after the cast. Before the cast you can check if the pointer you're trying to cast is actually the one you expect via RTTI:
if (typeid(b) == typeid(Derived1*))
{
// in this case it's safe to call the function right
// away without additional checks
dynamic_cast<Derived1*>(b)->SpecialD1DoSomething();
}
else
{
// do something else, like try to cast to Derived2 and then call
// Derived2::SpecialD2DoSomething() in a similar fashion
}
Checking it post-factum is actually a bit simpler:
Derived1* d1 = dynamic_cast<Derived1*>(b);
if (d1 != NULL)
{
d1->SpecialD1DoSomething();
}
I'd also say it's a bad practice to try and save typing while programming in C++. There are many features in C++ than seem to be completely fine to be typed shorter (i.e. makes you feel 'that NULL will never happen here'), but turn out to be a pain in the ass to debug afterwards. ;)

Some other things you might like to consider to avoid the use of dynamic_cast
From Effective C++ (Third Edition) - Item 35 Alternatives to virtual functions -
'Template Method pattern' via Non-Vitual Interface (NVI). Making the virtual functions private/protected with a public method 'wrapper' - allows you to enforce some other workflow of stuff to do before and after the virtual method.
'Strategy pattern' via function pointers. Pass in the extra method as a function pointer.
'Strategy pattern' via tr1::function. similar to 2. but you could provide whole classes with various options
'Strategy pattern' classic. Seperate Strategy from main class - push the virtual functions into another hierarchy.

There is a pattern named Factory Pattern that would fit this scenario. This allows you to return an instance of the correct class based on some input parameter.
Enjoy!

What is wrong with:
Base * b;
if( some_condition ) {
b = new Derived1;
}
else {
b = new Derived2;
}
if ( Derived2 * d2 = dynamic_cast <Derived2 *>( b ) ) {
d2->SpecialD2DoSomething();
}
Or am I missing something?
And can OI suggest that when posting questions like this you (and others) name your classes A, B, C etc. and your functions things like f1(), f2() etc. It makes life a lot easier for people answering your questions.

One way to avoid dynamic_cast is to have a virtual trampoline function "SpecialDoSomething" whose derived polymorphic implementation calls that particular derived class's "SpecialDxDoSomething()" which can be whatever non-base class name you desire. It can even call more than one function.

Related

dynamic_cast vs virtual AsDerived method in base

When trying to access derived class behaviour, the most common approach I read about is using dynamic_casts, i.e. dynamic_cast<DerivedA*>(BasePtr)->DerivedAOnlyMethod(). This isn't really pretty, but everybody understands what's going on.
Now I'm working on a code where this conversion is handled by virtual functions exported to the base class, for each derived class, i.e.:
class Base
{
public:
virtual DerivedA* AsDerivedA() { throw Exception("Not an A"); }
virtual DerivedB* AsDerivedB() { throw Exception("Not a B"); }
// etc.
};
class DerivedA : public Base
{
public:
DerivedA* AsDerivedA() { return this; }
};
// etc.
Use is then BasePtr->AsDerivedA()->DerivedAOnlyMethod(). Imho, this clutters up the base class, and exposes knowledge about the derived classes it shouldn't need.
I'm too inexperienced to say with certainty which is better, so I'm looking for arguments for and against either construct. Which is more idiomatic? How do they compare regarding performance and safety?
Well, putting the AsDerived#-methods into the base-class certainly leads to potentially faster casting.
If you cap the inheritance-hierarchy using final that advantage might be reduced or removed though.
Also, you are right about it being uncommon because it introduces clutter, and it introduces knowledge of all relevant derived classes into the base-class.
In summary, it might sometimes be useful in a bottleneck, but you will pay for that abomination.
Without seeing more code it is difficult to offer too much advice. However, needing to know the type of the object you're calling into argues more for a variant than a polymorphic type.
polymorphism is about information hiding. The caller should not need to know what type he is holding.
something like this, perhaps?
struct base
{
virtual bool can_do_x() const { return false; }
virtual void do_x() { throw std::runtime_error("can't"); }
virtual ~base() = default;
};
struct derived_a : base
{
virtual bool can_do_x() const { return true; }
virtual void do_x() { std::cout << "no problem!"; }
};
int main()
{
std::unique_ptr<base> p = std::make_unique<derived_a>();
if (p->can_do_x()) {
p->do_x();
}
}
Now we're talking to the object in terms of capabilities, not types.
Your intuition is right, the AsDerivedX methods are clutter. The fact that at runtime it can be checked whether these virtual functions were overloaded is equivalent to the cost of a typecheck. So, in my opinion, the C++ way of doing this is:
void doSomething(Base *unsureWhichAorB) {
DerivedA *dA = dynamic_cast<DerivedA*>(unsureWhichAorB);
if(dA) //if the dynamic cast failed, then dA would be 0
dA->DerivedAOnlyMethod();
}
Note that the check for non-zeroness of dA is critical here.
You are totally correct that such a solution not only clutters the base class but also puts unnecessary dependencies on it. In a clean design the base class does not need to and actually should not know anything about its derived classes. Everything else will become a maintenance nightmare pretty soon.
However, I'd like to point out that I am in the "try to avoid dynamic_cast"-Team. Meaning that I often see dynamic_cast that could have been avoided with a proper design. So the question to ask in the first place would be: Why do I need to know the derived type? Usually there is either a way to solve the problem by using polymorphism correctly or "losing" the type information already was the wrong path.
Prefer to use polymorphism instead of dynamic_cast:
class Base
{
public:
virtual void doSomething() = 0;
};
class DerivedA : public Base
{
public:
void doSomething() override { //do something the DerivedA-way };
};
class DerivedB : public Base
{
public:
void doSomething() override { //do something the DerivedB-way };
};
// etc.

Call an interface function from an unknown derived class (multiple inheritance)

I have an array of Base* objects. This holds a bunch of derived objects, some of which may implement an Interface.
struct Base {
virtual void doNotCallThis() { cout << "nooo" << endl; }
};
struct Interface {
virtual void doThis() = 0;
};
// Example derived class
struct Derived : Base, virtual Interface {
virtual void doThis() { cout << "yes" << endl; }
};
int main() {
Base* b[1];
b[0] = new Derived(); // Here would be a bunch of different derived classes
((Interface*)b[0])->doThis(); // Elsewhere, doThis() would be called for select array elements
return 0;
}
Output:
nooo
I don't know the exact type of b[i] at run time, so I can't cast to Derived (it could be Derived2, Derived3, etc). I also can't use dynamic_cast if that's a solution. All I know is that, by the time I call doThis(), b[i] is a type that inherits from Interface. The way I attempted to call it above causes the wrong function to be called, eg. Base::doNotCallThis().
How can I call it properly?
As other people have pointed out, you would probably do best to find a way to refactor your design so that casting isn't necessary.
But putting that aside, I can explain what's going wrong and how to correctly cast.
The problem with ((Interface*)b[0]) is that since Base and Interface are unrelated the compiler has to do a blind reinterpretive cast. Practically speaking that means in this situation the resulting pointer doesn't actually line up with the Interface part of the object. If you were to try static_cast<Interface*>(b[0]) you would find it doesn't compile - and that's a big hint that it's the wrong kind of cast to be making.
On the other hand, the compiler does know the relationship from Base to Derived and also from Derived to Interface. So as long as you know for sure that the object not only implements Interface but also is a Derived then you can do:
static_cast<Interface*>(static_cast<Derived*>(b[0]))->doThis();
However if your design has multiple different derived types which independently implement Interface then you might not be able to do that unless again you absolutely know what the derived type is at any time you go to make the call. - This is why refactoring it into a better class hierarchy is more desirable, since it's much less fragile and cumbersome to work with.
(As a side note, this issue points out why it's a great idea to never use raw/reintrepretive casts when moving up and down a class hierarchy. At least use static_cast since the can compiler better help you do it correctly.)
Writing an answer with the risk of being downvoted:
If we start with::
struct Base()
{
virtual void SomeFunc();
};
struct Interface
{
virtual void doThis();
}
then to create a bunch of derived functions from Base that are also interfaces, I'd do something like this:
struct BaseInterface : public Base, public Interface
{
// Nothing here - this is just combining Base and Interface
};
struct Base1 : public BaseInterface
{
... add stuff that Base1 has that isn't in Base.
};
struct Derived: public Base1
{
... some more stuff that isn't in Base1
}
And then we use it in Main like this:
int main() {
BaseInterface* b[1];
b[0] = new Derived(); // Here would be a bunch of different derived classes
b[0])->doThis(); // Elsewhere, doThis() would be called for select array elements
return 0;
}

PostActive visibility of class methods

I have here this abstract base class called base_class defined as it follows:
class base_class
{
public:
virtual ~base_class() = 0 {}
virtual size_t area() const = 0;
protected:
base_class() {}
};
One derived class from with it:
template <typename T> class A : public base_class
{
public:
A();
~A();
size_t area() const;
void display();
(...) etc code
};
And another class still derived from it:
template <typename T> class B : public base_class
{
public:
B();
~B();
size_t area() const;
void set();
(...) etc code
};
Than I have this instantiation and function call:
base_class *p = new A<int>;
p->display();
delete p;
p = new B<float>;
p->set();
(...) code
As you might already have observed, is that the pointer p won't "see" display and set methods.
The question is: when using pointers of type base_class, is there a chance of letting a derived object call derived methods that are only defined in the class that it points to? Thus being able to access display and set methods without having to make them virtual in the base class.
Otherwise we would have to make 2 virtual functions in the base_class, display and set, and that's very inconvenient, because A doesn't have to inherit set method, and B the display method.
You can use dynamic_cast to downcast from base class to derived class, if could not determine the runtime type of the object.
base_class *p = new A<int>;
if (A<int> *pa = dynamic_cast<A<int> *>(p))
pa->display();
delete p;
p = new B<float>;
if (B<float> *pb = dynamic_cast<B<float> *>(p))
pb->set();
If the type of object could be confirmed at compile time, static_cast can do the cast too, but beware: You are telling the compiler that you know for a fact that what is being pointed to really is of that type. If you are wrong, then the cast cannot inform you of the problem (as could dynamic_cast, which would return a null pointer if the cast failed, or throw a std::bad_cast for a reference cast failure) and, at best, you will get spurious run-time errors and/or program crashes.
Anyway, the best practice should be rearrange the inheritance relationship, try to use virtual function, avoid downcasts.
I am not quite sure what you ultimately want to do but its not usually good practice to call a function from the derived class that is not virtual in the base class using a pointer to a base class. As was already mentioned, you can use type casting to achieve this, but you need to check if the dynamic_cast was possible before attempting to call the function.
Have you considered creating a pure virtual function in the base class such as:
public:
virtual void doIt() = 0;
Then you could implement this in the derived classes to call the function you want:
class A
{
void doIt()
{
display();
}
};
class B
{
void doIt()
{
set();
}
};
There's actually no way of accessing the members since for all the program knows it wouldn't have to be a derived class, and could just be the base class. This meaning casting as mentioned in the comments.
A pointer is simply an integer, for 32bit OS's it's a 32 bit int, for 64bit well i guess you could guess right? 64bit integer.
When it comes to typing pointers to actual classes and structures etc, it's up to the API to decide whether or not to display the function, it's more of a helper.
As for the program only knows it's a base class pointer you can only access it's variables. However if you are 100% sure what you are dealing with and you want to save performance here's something somewhat pseudo code.
typedef void (A::*func)(void*);
func f = &A::set;
base_classPointer->*f();
But to be safe and sound either from the beginning make the pointer of the actual class as it seems you will be sure of that it's actually an A class.
Or use yourself of the dynamic, static, casts.
if(B * b = static_cast or dynamic_cast<B*>(mypointer))
Now I do suggest that you use yourself of exact pointer types if you are completely sure of what it's going to be. Or use yourself of the casts. If you are really anxious about performance, try the simple delegate method.

Is there a way to infer the type of an object?

This may be a stupid question, I suspect I know the answer (no) because I seem to be hitting a wall here.
Given I have a collection of objects derived from certain class:
class BaseClass;
class DerivedA: public BaseClass;
class DerivedB: public BaseClass;
class DerivedC: public BaseClass;
std::vector<BaseClass> myCollection;
I want to call a method depending on the types of the specific class:
class Processor {
void doSomething(DerivedA a, DerivedB b);
void doSomething(DerivedA a, DerivedC c);
}
The problem is, if I access the individual items on the collection and try to call the 'doSomething' method in the 'Processor', it will not be able do decide which method to use (afaik). So my question is: Is there any way to fetch the items in the collection with the right derived-type?
If you are going to keep the doSomething method as it is, this is what is called multiple dispatch and is NOT currently supported by C++.
If it were a virtual member function of BaseClass then yes it would be the run of the mill C++ polymorphism on the object it is being invoked on, but it would still NOT automatically infer the type of the arguement.
To get around this you can do something like what is suggested in the earlier link
void collideWith(Thing& other) {
// dynamic_cast to a pointer type returns NULL if the cast fails
// (dynamic_cast to a reference type would throw an exception on failure)
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Asteroid-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Asteroid-Spaceship collision
} else {
// default collision handling here
}
}
Basically keep casting to various possible Derived classes until one works and call one of the methods appropriately(no special effort since the compiler knows what type you are trying to cast to).
IMPORTANT: as #WhozCraig points out, your vector needs to hold pointers to avoid Object-Slicing and render this whole question moot.
Ok, yes you should use polymorphism as the above stated. If your function needs to handle 2 objects though it gets extremely complicated.
If the derivations form a limited set and know each other you can use double-dispatch. It's not perfect but it solves this particular case.
class DerivedA;
class DerivedB;
class DerivedC;
class BaseClass
{
public:
virtual ~BaseClass();
virtual void doSomethingWithBase( BaseClass & b2 ) = 0;
virtual void doSomethingWithDerivedA( DerivedA & da ) = 0;
virtual void doSomethingWithDerivedB( DerivedB & db ) = 0;
virtual void doSomethingWithDerivedC( DerivedC & dc ) = 0;
};
class DerivedA : public BaseClass
{
public:
void doSomethingWithBase( BaseClass & b2 )
{
b2.doSomethingWithDerivedA( *this );
}
void doSomethingWithDerivedA( DerivedA & da )
{
// implement for two DerivedA objects
}
void doSomethingWithDerivedB( DerivedB & db )
{
// implement for an A and B
}
void doSomethingWithDerivedC( DerivedC & dc )
{
// implement for an A and C
}
};
// implement DerivedB to call doSomethingWithDerivedB on its parameter
// implement DerivedC to call doSomethingWithDerivedC on its parameter.
You get the idea. From where you call you don't need to know which two types you have and you never need to actually look this up. But if you ever add more implementations you have a lot of code to edit and may consider some kind of lookup table.
If you need a class to define itself you can use some kind of virtual id.
class BaseClass
{
public:
virtual int id() const = 0;
};
and then you get the classes to reveal their ids and find the handler in the table based on these ids that wil handle the two objects. The ids don't have to be ints, they can be strings which makes it easier to avoid naming clashes, and this has the advantage over the double-dispatch method of the base class not knowing its derived classes or them knowing each other, and being extensible. You also don't have to handle every pair.

Downcasting a pointer using a function instead of giant if statement

I have a vector with pointers of type Vehicle. Vehicle is the base class and there are many derived types like MotorCycle, Car, Plane, etc. Now, in my program there comes a point where I need the derived type while traversing the vector. Each Vehicle class has a GetType() function which returns an int which tells me what the derived type is (motorcylce, car, plan). So, I can use a dynamic cast to downcast to the derived type from the base class pointer. However, I need to have a giant if statement everytime I need the derived pointer
if(vehicle_ptr->GetType() == PLANE)
Plane *ptr = dynamic_cast<Plane*> vehicle_ptr;
else if (vehicle_ptr->GetType() == MOTORCYCLE)
MotorCycle *ptr = dynamic_cast<MotorCycle*> vehicle_ptr;
..and on and on.
Is there a way to have a function or some trick I can call that would save me from the giant if statement everywhere? Like ::GetDerivedPtr(Vehicle *ptr). Would a template class help here? (never used them before) Sorry, my C++ is a bit rusty and I did search but these terms bring up too much material to find what I'm looking for. Thanks.
It looks like you've manually tried to recreate polymorphism. You don't need a type member. This is almost always a bad idea. Use polymorphism and virtual functions.
When you have a vehicle pointer v and do
v->function();
It will call the proper function for whatever type (Plane, Train, or Automobile) that the pointer actually points to if function is a virtual function. What you're doing is already handled by the language.
So:
class A {
public:
virtual void f() {cout << "A";}
};
class B : public A {
public:
virtual void f() {cout << "B";}
};
int main(){
A *a;
B b;
a = &b;
a->f();
}
The above snippet will print B.
I second the idea that you need some virtual function and a common base type. Imagine that there is some way to get the pointer which has the correct type. What will you do with it then? You'll have to make a giant switch anyway, because you call specific functions for each of your specific types.
One solution would be to invent a name for the operation you are trying to execute, and put its implementation as a virtual function at each specific Vehicle class. If the operation accepts different parameter for each of the cases, the parameters have to be packed into a special polymorphic structure/class, but here maybe the Visitor pattern is a more generic solution.
First check whether what you're going to do can be done simply via virtual functions in class Vehicle, overridden by each derived class.
If not, then consider the Visitor Pattern.
Cheers & hth.,
dynamic_cast will check the type itself (you don't need your own variable for this). You can do the following instead:
Plane *plane_ptr = dynamic_cast<Plane*>(vehicle_ptr);
if(plane_ptr != NULL)
{
// Do stuff with 'plane_ptr' that you couldn't do with 'vehicle_ptr'
}
I don't really see how creating a function to do the cast would help because you still need to class specific code anyway (and the function would have a fixed return type, so the closest you could get is something like the 'dynamic_cast' call, which is pretty much a standard function anyway).
Use Visitor based dispatching. Observe that not a simple cast of any kind is required in the follwing (somewhat trivialized) example:
// simple cyclic visitor
class VehicleVistor {
public:
// add overload for each concrete Vehicle type
virtual void Visit(class Motorcycle&) {};
virtual void Visit(class Plane&) {};
virtual void Visit(class Car&) {};
};
class Vehicle {
public:
virtual Accept(VehicleVisitor&) = 0;
};
class Car : public Vehicle {
public:
virtual Accept(VehicleVisitor& pVisitor) {
pVisitor.Visit(*this);
}
};
// and so on...
At some point of you program you need to retrieve all instances of, say Motorcycle:
class MotorcycleExtractingVisitor : public VehicleVisitor {
std::vector<Motorcycle*> mMotorcycles;
public:
void operator()(Vehicle* pVehicle) {
pVehicle->Accept(*this);
}
void Visit(Motorcycle& pMotorcycle) {
mAllMotorcycles.push_back(pMotorcycle);
}
std::vector<Motorcycles*> Get() { return mAllMotorcycles; }
};
class Extractor {
public:
// here you extract motorcycles
static std::vector<Motorcycle*> ExtractMotorcycles(std::vector<Vehicle*>& pVehicles) {
MotorcycleExtractingVisitor tMotos;
std::for_each(pVehicles.begin(), pVehicles.end(), tMotos);
return tMotos.Get();
}
// this would be a templatized version, left as exercise to the reader
template<class TExtracted, classtypename TBegItr, typename TEndItr>
static std::vector<TExtracted*> Extract(TBegItr pBeg, TEndItr pEnd) {
ExtractingVisitor<TExtracted> tRequiredVehicles;
std::for_each(pBeg, pEnd, tRequiredVehicles);
return tRequiredVehicles.Get();
}
};
Usage is as follows:
// fixed type version:
std::vector<Motorcycles*> tMotos =
Extractor::Extract(tVehicleVector);
// templatized version (recommended)
std::vector<Motorcycles*> tMotos =
Extractor::Extract<Motorcycles>(
tVehicleVector.begin(),tVehicleVector.end());