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;
}
Related
Sorry for the title's wording; I don't know how to make it better. But the gist of my question is this:
#include <iostream>
using namespace std;
class Base {};
class Base2 {};
class C : public Base, public Base2 {};
class D : public Base {};
void isDerivedFromBase2(Base *p) {
if (...) { /* test whether the "real object" pointed by p is derived from Base2? */
cout << "true" << endl;
}
cout << "false" << endl;
}
int main() {
Base *pc = new C;
Base *pd = new D;
isDerivedFromBase2(pc); // prints "true"
isDerivedFromBase2(pd); // prints "false"
// ... other stuff
}
How do I test if an object, represented by its base class pointer Base *, is derived from another base class Base2?
You can perform dynamic_cast like this:
if (dynamic_cast<Base2 *>(p)) {
online_compiler
Unlike approach with typeid this one does not require an extra header to be included, however it relies on RTTI as well (this implies that these classes need to be polymorphic).
This sounds like an X-Y problem.
The need for RTTI (or the need to test an object for which class it is derived from) is typically a sign for a bad design - you simply should not ever need such a test/information.
If the hierarchy is well designed, virtual functions take on the role of these tests.
To find out what is not well-designed, ask yourself 'what I am going to do with the information once I have it?' The answer is always something of the kind 'I'll make an if/switch/... to treat them differently'; and the correct solution is to treat them the same way - call a virtual method, and each object carries the knowledge of the right virtual method which knows what it needs to get done.
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.
Here is the problem, I have a vector of pointers to an abstract base class filled with derived objects like so:
class AbstractBase { /* ... */ };
clase Derived1 : public AbstractBase {
Derived1() { }
Derived1( const AbstractBase& abc ) { /* ... */ }
};
/* ... */
vector< AbstratcBase* > lThingies;
const AbstractBase& getThingie(int pos) {
return *lThingies[pos];
}
And to get copies of the elements I use the derived class "copy constructor" like so:
Derived1 d1 = getThingie(2);
But the problem is that I don't like this: There is no way to force the implementation of this "copy constructor" when building the class "derived42" and even when you do remember it's very easy to get it wrong (like making it a recursive call, happened to me).
My question is: Is there a better way to do this? how?
Update:
One of the "unwritten" requirements of the solution that I'm looking for is to get a copy of the derived object as a local variable, so I don't forget to delete it.
More info:
There are a number of lThingies and, at runtime, I can tell what are the derived objects contained within (derived1, derived2, etc.), but not at compile time.
You could make a pure virtual clone function in AbstractBase which returns an AbstractBase pointer, and override clone in your derived classes.
STRICTLY OPINION:
This is sort of a gross and outdated practice though (in my opinion). I suggest re-architecting to eliminate the need to do this in the first place.
To elaborate on my 'gross and outdated' opinion of the virtual constructor idiom (I'm sure this will be controversial):
To actually be robust/generic clone would need to be templated for an allocator, like some STL constructs are. But, it can't be.
When do you actually want to copy an object of which you don't know the concrete type? I question the legitimacy of that use case.
Do you know your getThingie returns a Derived1? If you know this, possibly you should change the return type of Derived1 and the storage in the std::vector to be Derived1 instead of AbstractBase.
Assuming the above doesn't work, you can do a Derived1 bob = dynamic_cast<Derived1&>(getThingie(...));, which does a run-time check that the thingy is a Derived1 or more derived instance, and if so it does the cast -- if not, it throws an exception.
If you don't want to bother with the run time check because you are so certain that it is a Derived1, simply use Derived1 bob = static_cast<Derived1&>(getThingy(...));.
However, working with actual instances of classes which have an inheritance hierarchy is very questionable. There are many, many things that can go wrong.
class A
{
public:
virtual void toto() { std::cout << "Love Java" <<std::endl; }
virtual A&& Duplicate() { return std::move(A()); }
};
class B : public A
{
public:
virtual void toto() { std::cout << "Love C++11" <<std::endl; }
virtual B&& Duplicate() { return std::move(B()); }
};
int main()
{
A *a = new B();;
A&& b(a->Duplicate());
a->toto();
b.toto();
}
In the main you create a B on stack without know his type. (with rvalue reference in c++11)
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());
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.