Polymorphism and checking if an object has a certain member method - c++

I'm developing a GUI library with a friend and we faced the problem of how to determine whether a certain element should be clickable or not (Or movable, or etc.).
We decided to just check if a function exists for a specific object, all gui elements are stored in a vector with pointers to the base class.
So for example if I have
class Base {};
class Derived : public Base
{
void example() {}
}
vector<Base*> objects;
How would I check if a member of objects has a function named example.
If this isn't possible than what would be a different way to implement optional behaviour like clicking and alike.

You could just have a virtual IsClickable() method in your base class:
class Widget {
public:
virtual bool IsClickable(void) { return false; }
};
class ClickableWidget : public Widget
{
public:
virtual bool IsClickable(void) { return true; }
}
class SometimesClickableWidget : public Widget
{
public:
virtual bool IsClickable(void);
// More complex logic punted to .cc file.
}
vector<Base*> objects;
This way, objects default to not being clickable. A clickable object either overrides IsClickable() or subclasses ClickableWidget instead of Widget. No fancy metaprogramming needed.
EDIT: To determine if something is clickable:
if(object->IsClickable()) {
// Hey, it's clickable!
}

The best way to do this is to use mixin multiple inheritance, a.k.a. interfaces.
class HasExample // note no superclass here!
{
virtual void example() = 0;
};
class Derived : public Base, public HasExample
{
void example()
{
printf("example!\n");
}
}
vector<Base*> objects;
objects.push_back(new Derived());
Base* p = objects[0];
HasExample* he = dynamic_cast<HasExample*>(p);
if (he)
he->example();
dynamic_class<>() does a test at runtime whether a given object implements HasExample, and returns either a HasExample* or NULL. However, if you find yourself using HasExample* it's usually a sign you need to rethink your design.
Beware! When using multiple inheritance like this, then (HasExample*)ptr != ptr. Casting a pointer to one of its parents might cause the value of the pointer to change. This is perfectly normal, and inside the method this will be what you expect, but it can cause problems if you're not aware of it.
Edit: Added example of dynamic_cast<>(), because the syntax is weird.

If you're willing to use RTTI . . .
Instead of checking class names, you should create Clickable, Movable, etc classes. Then you can use a dynamic_cast to see if the various elements implement the interface that you are interested in.
IBM has a brief example program illustrating dynamic_cast here.

I would create an interface, make the method(s) part of the interface, and then implement that Interface on any class that should have the functionality.
That would make the most sense when trying to determine if an Object implements some set of functionality (rather than checking for the method name):
class IMoveable
{
public:
virtual ~IMoveable() {}
virtual void Move() = 0;
};
class Base {};
class Derived : public Base, public IMoveable
{
public:
virtual void Move()
{
// Implementation
}
}
Now you're no longer checking for method names, but casting to the IMoveable type and calling Move().

I'm not sure it is easy or good to do this by reflection. I think a better way would be to have an interface (somethign like GUIElement) that has a isClickable function. Make your elements implement the interface, and then the ones that are clickable will return true in their implementation of the function. All others will of course return false. When you want to know if something's clickable, just call it's isClickable function. This way you can at runtime change elements from being clickable to non-clickable - if that makes sense in your context.

Related

Is it possible to dynamic_cast between two unrelated types, if they share a common (possibly unknown) child class?

Sorry if the question title makes no sense, but I'm not sure how to succinctly describe the problem I'm trying to solve. Here's the issue:
I'm working with a C++ library that makes heavy use of a class which we'll call Base
This library has several different child classes that inherit from Base. We'll call these classes Child1, Child2, .. etc.
This library allows the user create their own child classes of Base and have the library use instances of those classes. I currently have something like this:
class Custom : public Child1 // inherit from Child1, which inherits from Base
{
public:
// override virtual functions here
// ...
void doSomething(); // Utility function I created
}
and then the library I'm using will have some function like this:
void foo(Base* base);
I can pass in a pointer to my Custom class no problem, everything's fine. There are also times where I might need to receive a pointer to a Base object from the library and do stuff with it. That looks something like this:
// code...
Base *base = getSomeBase(); // getSomeBase() is a function from the library that returns a Base*
Custom* myCustom = static_cast<Custom*>(base); // I always make the library use my `Custom` class, so this is safe.
myCustom->doSomething();
This also works without issue. I'm able to invoke my custom doSomething() method by performing a static_cast. However...I now have the need to have more than one possible Custom class. Specifically, I need make the appropriate "child" class to inherit from a template parameter in my Custom class. My code now looks like this:
template <class Child_t>
class Custom : public Child_t // inherit from Child_t, which inherits from Base
{
public:
// override virtual functions here
// ...
void doSomething(); // Utility function I created
}
There is no issue in making the library use my new templated Custom<> class because as long as the template parameter Child_t is in fact one of the library's child classes that inherit from Base, my Custom<> class can simply be cast to a Base*. The issue arises when trying to go in the other direction:
Base *base = getSomeBase();
/* ?????
Would like to call base->doSomething();
But I have no idea which Custom class I have received here. "base" could be
a Child1*, Child2*, etc. There's no way for me to perform a cast.
*/
I am stuck. Note that my function doSomething() will have identical behavior regardless of which Custom<> class I have received from the library. My initial thought was to move my doSomething() function to an interface class.
class Interface
{
public:
virtual void doSomething() = 0;
}
And then have each Custom<> class implement the interface like so:
template <class Child_t>
class Custom : public Child_t, public Interface
{
void doSomething() override;
}
This ends up being unhelpful, as the compiler will not allow me to do the following:
Base *base = getSomeBase();
Interface* interface = static_cast<Interface*>(base); // Error: can't static_cast between unrelated types.
interface->doSomething();
The compiler says that Interface and Base are unrelated types. I know for a fact that any Base* I receive is actually an Interface*, but the compiler can't know that and, I'm guessing, cannot perform the correct pointer adjustment to convert the Base* to an Interface*. At this point I'm stuck and am not sure what to do. I need to call my doSomething() function on whatever Base* I get from the library, but I have no idea which custom child class I'm actually getting. The only solution I currently see is to exhaustively dynamic_cast to every possible child class.
Base *base = getSomeBase(); // getSomeBase()
if (auto* c1 = dynamic_cast<Custom<Child1>*>(base))
{
c1->doSomething();
}
else if (auto* c2 = dynamic_cast<Custom<Child2>*>(base))
{
c2->doSomething();
}
This is an ugly solution. It also places extra cognitive load on the developer because if at any point they decide they need to use a Custom<Child3>, Custom<Child4>, Custom<Child5>, etc. class, they must remember to go back and update the if-else chain to exhaustively check for each possible case. So my question is:
Is it possible to somehow invoke my doSomething() function on the Base* object without actually knowing which Custom<> class I have at compile time, and without simply trying every possible dynamic_cast? Hence the title of my question: can I somehow cast a Base* to an Interface*, given that I know for a fact that they share a common child class (I just don't know which child class).
Am I going about this in the completely wrong way?
you should use dynamic_cast<Interface*>(base)
struct B{virtual ~B(){}};
struct I{virtual int foo()=0;};
struct X:B{};
struct Y:I,X{virtual int foo(){return 10;}};
struct Z:I,X{virtual int foo(){return 20;}};
int main(){
B* x = new Z;
I* i = dynamic_cast<I*>(x);
return i->foo();
}
http://coliru.stacked-crooked.com/a/f7a5787cb9fe80be

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.

concept of virtual functions in c++?

I read so many blogs and I understand how to use virtual function in c++. But, still I don't understand why we use virtual functions. Can you give me a real world example so that I can more easily visualize the actual meaning of virtual function.
An important thing to mention is that inheritance (which the keyword virtual is fundamental for) should not be for the sole purpose of code re-use, use delegation for this.
Delegation would be when we have a class say BroadbandConnection with a method called connection(). Then your manager says we want to add encryption, so you create a class BroadbandConnectionWithEncryption. Your natural instinct may be to use inheritance and then make the new class BroadbandConnectionWithEncryption derive from BroadbandConnection.
Drawback's to this is that the creator of the initial class had not designed it for inheritance so you would need to change its definition to make the method connection() virtual so you can override its behavior in the derived class. This is not always ideal. A better idea is to use delegation here for the purpose of code reuse.
class BroadBandConnection
{
public:
void Connection (string password)
{
//connection code.
}
};
class BroadBandConnectionWithEndcryption
{
public:
void Connection (string password)
{
mbroadbandconnection.Connection(password);
//now do some stuff to zero the memory or
//do some encryption stuff
}
private:
BroadBandConnection mbroadbandconnection;
};
The keyword virtual is used for the purpose of polymorphism. As the name suggest, it is the ability for an object to have more than one form. This sort of decision would be made at the time of designing an interface or class.
class IShape
{
virtual void Draw () = 0;
};
class Square
{
void Draw()
{
//draw square on screen
}
};
class Circle
{
void Draw()
{
//draw circle on screen
}
};
I made Draw() pure virtual with the = 0. I could have left this out and added some default implementation. Pure virtual makes sense for Interfaces where there is no reasonable default implementation.
What this lets me do is pass around a Shape object to various methods and they do not need to be concerned with what I have just given them. All they know is that I have to provide something that supports the ability for a shape to draw itself.
IShape* circle = new Circle ();
IShape* square = new Square ();
void SomeMethod (IShape* someShape)
{
someShape->Draw(); //This will call the correct functionality of draw
}
In the future as people begin thinking of new shapes, they can derive from IShape and so long as they implement some functionality for Draw. They can pass this object to SomeMethod.
First, this.
Now, a real life example. I have a program with a GUI with three tabs. Each tab is an object of a class that derives from a common base, TabBase. It has a virtual function OnActivate(). When a tab is activated, the dispatcher calls it on the current tab. There's some common action and there are actions that are specific to this tab. This is implemented via virtual functions.
The benefit is that the controller does not need to know what kind of tab it is. It stores an array of TabBase pointers, and just calls OnActivate() on them. The magic of virtual functions makes sure the right override is called.
class TabBase
{
virtual void OnActivate()
{
//Do something...
}
};
class SearchTab: public TabBase
{
void OnActivate() //An override
{
TabBase::OnActivate(); //Still need the basic setup
//And then set up the things that are specific to the search tab
}
}
We have one base class (animal) that have method, that can be implemented differently by it's children (say). When we declare this method virtual, we can adress that method and it will be implemented from it's children's definition. You don't have to use virtual if you adress children's overloaded methods, but you have to, when you adress parent's methods.
For example, if you have a vector of animals each one of whom is different. You declare method (say) as virtual and call it from animal class and it will be called from corresponding child.
Correct me if I'm wrong, that's how I understood it.
They actually give an example on Wiki
http://en.wikipedia.org/wiki/Virtual_function
using animals. Animals is the super class, all animals eat (the superclass virtual function). Each animal may eat differently than all the other animals (overriding the virtual function). I have a list of arbitrary animals, and when I call the eat function, they will display their own differing eating habit.
If you are familiar with Java - that should be easy. In Java, ALL class methods are effectively virtual. If you override it in a derived class, and you call it via a base class reference, the override will be called, not the base.
That's not the default behavior in C++. If you want a function to behave in that way, you have to declare it as virtual in the base class. Easy enough.
Java is choke full of virtual functions. It just does not have an explicit keyword for them.
The purpose of virtual functions is to achieve dynamic dispatch.
You say you are familiar with Java, so then for a real world use of virtual functions, think of any place in Java where you would have used an interface or used #Override on a public/protected method.
The decision to use virtual functions is a simple matter. You just need to know when you'd want to override a base method. Take the following code as an example:
class animal
{
public:
void sound()
{
cout << "nothing";
}
};
class bird : public animal
{
public:
void sound()
{
cout << "tweet";
}
};
In this case, I'd want to override bird(). But what if I didn't? This is what would happen:
animal * a = new bird;
a->sound();
**Output**
nothing
The screen would say nothing because for all intents and purposes, C++ only sees an animal. However, if you declared it virtual, it knows to search for the lowest method in the class hierachy. Try it again:
class animal{
public:
virtual void sound(){cout<<"nothing";}
};
class bird : public animal
{
public:
void sound()
{
cout << "tweet";
}
};
animal * a = new bird;
a->sound();
**Output**
tweet.
Hope this helps.

Is it possible to have a base class method that calls the same (but overridden method) of all it's derived classes?

It's a bit hard to explain in words, so I'll give an example:
(The following code might have incorrect syntax but it suffices to give an idea)
class A
{
public:
static void Update(UINT someValue);
};
class B : public A
{
public:
static void Update(UINT someValue);
};
class C : public A
{
public:
static void Update(UINT someValue);
};
I know static members function do not override each other,
but let's suppose they do.
What I want to achieve, is when A::Update(someValue); is called,
It should implicitly call B::Update(someValue), and also C::Update(someValue), as well as call every static void Update(UINT someValue) method of other classes derived from A
Is this possible in one way or another?
And if it is, how would you do it?
I think you should be using composite pattern instead. You can read about it at http://en.wikipedia.org/wiki/Composite_pattern and http://www.javacamp.org/designPattern/composite.html
That info below my comment is not enough to have a clear idea about your code but I was thinking if it is possible to do something similar to what C# does with events, where you can register events and the class that triggers then (your base class in that case) can implement a list of function pointers (pointing to the derived methods, which in that case you have to have instances of the derived classes) and call all of then iterating this list. Just an idea, don't know if this is what you need.
There's no way to do it automatically. A simple way to get the effect is for each derived class to call the function of its base class:
class A
{
public:
static void Update(UINT someValue) {
std::cout << "A\n";
}
};
class B : public A
{
public:
static void Update(UINT someValue) {
A::Update(someValue);
std::cout << "B\n";
}
};
If you prefer to work from bottom to top, you could have each class do its work before calling the derived class. Of course there's nothing to stop a derived class from implementing Update and not calling its base class. It is however fine for a class to not implement Update at all -- it doesn't care about updates, but its base class's function can still be called. So it's not a huge burden on implementers, they just have to follow the rule that if they implement the function, they have to call the base.
Another way might be for the base class to keep a list of "listeners" who are interested in updates, and to call them in turn whenever an update occurs. Each derived class can then register a suitable listener.
It might be difficult to make code like this exception-safe, though, if each level makes changes but one or more levels may throw.

A cleaner code alternative to polymorphism

Building a GUI system and I have a few classes for different GUI components that derive from a base "GUIcontrol" class. What I want is to have just one function to return any type of component but be able to work with the functions specific to that component type (functions of the derived class). I noticed that the polymorphism approach is going to become a problem I have to declare all the derived functions in the base which is unnecessary for this, since I will never create an object just from the base class.
class GUIcontrol {
protected:
std::string _name;
// these two methods (along with name()) will be used by all types
virtual void position(/*parameters*/)
virtual void useImage(/*parameters*/)
// these should be only in derived types
virtual void setHotSpot(/*parameters*/);
virtual void setScrollButtons(/*parameters*/);
public:
std::string name();
/*etc*/
}
class GUIbutton : public GUIcontrol {
public:
void setHotSpot(/*parameters*/);
}
class GUIscrollBar : public GUIcontrol {
public:
void setScrollButtons(/*parameters*/);
}
GUIcontrol* GUIsystem::getControl(std::string name);
The problem with this is that if I want to add more functions unique to GUIbutton or GUIscrollBar, or any functions to other derived GUI classes, I also have to declare them virtual in the base class so the compiler doesn't complain about something like "setHotSpot" not being a member of the base class it returns.
The base class does have member functions that will apply to all the derived classes, such as telling the object where it should be positioned, what image it needs to use, what it should be called, etc. But I don't want to keep stuffing the base class with other functions that need to stay exclusive to certain derived classes.
As I keep adding more virtual functions I would end up with a huge blob object for the base class. Can I design this in a cleaner way? Note that I am still not sure if I want to use static_cast/dynamic_cast for getControl() to solve this but just want to know if there are any other ways around this to clean it up.
The base class should only contain methods for functionality common to all controls.
If you're going to use functionality that only makes sense for one type of control, you should be checking that the control is of the correct type anyway, and can then cast it to that type.
The base class is exclusively common functionality. If you want your method to behave differently for different controls, use dynamic_cast. If you want it to act the same for all controls, use a virtual method.
This is your problem:
What I want is to have just one
function to return any type of
component but be able to work with the
functions specific to that component
type (functions of the derived class).
What you want is to treat them the same but differently. Huh. I wonder how you're going to make that work. You need to decide if you want to treat them all the same, or if you want to treat them differently.
Type checking and then downcasting isn't the right way to do this. What you should be doing is placing generic methods onto your base class which perform the types of operations you want, and then overriding them in subclasses. For example, if you want the GUIControl to be able to draw itself, then put a doDraw() method on the base class, then override that in each subclass to do as is needed. If you instead put a getTitleBar(), getText() etc. methods on your subclass, then have the caller downcast and calls those specific methods depending on the type, your encapsulation is broken. If you have some common code that multiple subclasses need to do their drawing, then you factor this out either through another parent class, or through composition. Using dynamic_cast, or putting specific methods on the generic subclass, will likely make your code worse.
If I have this right: You want to be able to pass around base class objects but have a clean way to call specific derived class methods where the derived class implements those methods?
Sounds like the 'mixin' pattern might help:
struct Base
{
virtual ~Base() {}
};
struct Mixin
{
virtual ~Mixin() {}
virtual void mixedMethod() = 0;
};
struct Concrete : Base, Mixin
{
virtual void mixedMethod() { std::cout << "Mixing" << std:: endl; }
};
Base* create() { return new Concrete;}
bool mixIt(Base& b)
{
Mixin* m = dynamic_cast<Mixin*>(&b);
if (m)
m->mixedMethod();
return m;
}
void test ()
{
Base* b = create();
assert(mixIt(*b));
Base base;
assert(!mixIt(base));
}
[ Yes, real code never uses struct for polymorhic classes; just keeping it compact.]
The idea here is that the availability of a given method is encapsulated in the Mixin class, which is an pure abstract base class, possibly with only a single pure virtual function.
If you want "know" your base class object is of the derived type, you can call the mixin classes method. You can wrap the test and the call in a non-member function; this allows you to keep the base calss interface itself clean.