Here is some pseudo code of my setup:
class IMyClass { ... }; // pure virtual class
class CMyBaseClass { .... };
class CMyClass : public CMyBaseClass, public IMyClass { ... }
Then I have collection of CMyBaseClass*. I have custom RTTI that allows me to find out if a class implements given interface. So I can find which of the objects have IMyClass implementation. My problem is that I can't cast it to that interface. I don't want to use standard RTTI and dynamic cast.
I'm thinking in my custom RTTI to store some pointer diffs for casting between pair of classes, but I haven't figure out implementation that makes me happy.
Any other solutions?
Well, if you insist in not using the language RTTI, you can use just like the old COM: make all your classes or interfaces derive from the following interface:
class IMyCast // similar to IUnknown
{
public:
virtual void *CastTo(interfaceId_t id) = 0; //Similar to IUnknown::QueryInterface
};
Now in your CMyClass:
class CMyClass : public CMyBaseClass, public IMyClass
{
//...
void *CastTo(interfaceId_t id)
{
switch (id)
{
case IMyClass_id: //or whatever
return static_cast<IMyClass*>(this);
//...other cases
default:
throw std::bad_cast(); //or return NULL
}
}
};
Then in the user code:
CMyBaseClass *obj;
IMyClass *my = static_cast<IMyClass*>(obj->CastTo(IMyClass_id));
Probably you'll need to augment your custom RTTI; at least this is what I did in pretty much the same situation. Instead of using pointer diffs, my solution instantiates a "caster" function template for the necessary (Class, Interface) pairs. It's something like this:
All interfaces have a unique int id. For this a MyInterface needs to be derived from InterfaceBase. The id is assigned automatically on the first MyInterface::GetId() call.
The implementor of MyClass (that implements MyInterface) needs to add an IMPLEMENTS(MyClass, MyInterface) macro in a .cpp file.
The macro instantiates a void* GetInterface<C, I>(void*) function, and then registers a pointer to this function in an interfaceId -> GetInterface-function map (that belongs to class C). This function casts its argument into C*, then the C* into I*, and finally back to void*. (The hacking with void*'s is necessary so that all these functions have the same signature, thus they can be stored in a map.)
To get an interface, the user needs to call a myObject->GetInterface() function, implemented in CMyBaseClass. It finds the map that belongs to the dynamic class of the this object, looks up the appropriate caster function based on I::GetId(), and calls it passing this.
Related
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
Let's say I have an abstract base class that has two derived classes. Each of those derived classes has some new functionality not present in the abstract base class, but both derived classes have the same function. For example:
class MyBase:
public:
/* ... */
virtual void DoSomething() = 0;
/* ... */
class MyAlpha : public MyBase
public:
/* ... */
void DoSomething() { /* does sometihng */ }
/* Function not present in abstract base class */
void DoSomethingNew() { /* does something new */ }
/* ... */
class MyBeta : public MyBase
public:
/* ... */
void DoSomething() { /* does sometihng */ }
/* Function not present in abstract base class */
void DoSomethingNew() { /* does something new */ }
/* ... */
Now I have a templated function somewhere that accepts a pointer (in my case a std::unique_ptr) to the base class, and I want to be able to call the DoSomethingNew() function (the function that is present in both derived classes but not the base class. For example:
template <typename Base_t> void MyOperation(std::unique_ptr<Base_t> &base_object) {
/* some ops */
base_object->DoSomethingNew();
}
How do I go about doing this? I feel like template specialization might be the way to go here but I'm not quite sure. I am working on extending an open source library with a new feature, so I have limitation on what existing code I can/should modify to make my feature work. The base class in my actual use case is code that I'd like to avoid modifying, but for general use in this library, my function signature needs to accept a pointer to the base class.
As the base class is virtual, the actual usage is something like:
std::unique_ptr<MyBase> object = std::unique_ptr<MyAlpha>(new MyAlpha);
MyOperation(object);
How do I go about this using derived class functionality in the MyOperation() function? If it makes a difference, I have to stay C++11 compatible.
Each of those derived classes has some new functionality not present in the abstract base class, but both derived classes have the same function.
Then capture that in a possibly abstract intermediate class:
class MyMiddle : public MyBase {
public:
virtual void DoSomethingNew() = 0;
};
class MyAlpha : public MyMiddle {
public:
void DoSomething() override;
void DoSomethingNew() override;
};
class MyBeta : public MyMiddle {
public:
void DoSomething() override;
void DoSomethingNew() override;
};
This way you can implement the common functionality around DoSomethingNew by referencing MyMiddle, avoiding a lot of code duplication you might otherwise get.
Now I have a templated function somewhere that accepts a pointer (in my case a std::unique_ptr) to the base class, and I want to be able to call the DoSomethingNew() function.
Since you only have a pointer to the base class, the compiler will not out of the box allow you to call methods of a derived class on that. However, if you expect the implementation to actually be an instance of a derived class, you can cast to that.
Use a dynamic_cast to check whether the derived class is of the expected type and use it as that type if it is. Use a static_cast if you are 100% totally absolutely sure that the argument will always be of the derived class, now and forever in the future. In other words, don't. Go for dynamic_cast.
Note that dynamic_cast is available for raw pointers but not for unique_ptr. So you have two options: either keep the unique pointer to base and use a raw pointer to derived for access. Or cast the pointer in an elaborate multi-step procedure. The latter only makes sense if you want to hold on to the pointer for longer in a context where it needs to be of the derived type. The simple case goes like this:
void SomethingSimple(std::unique_ptr<MyBase> base) {
MyMiddle* derived = dynamic_cast<MyMiddle>(base.get());
if (derived == nullptr) {
// derived wasn't of the correct type, recover in a reasonable way.
return;
}
derived->DoSomethingNew();
}
The more complex pointer cast goes like this instead:
void SomethingComplicated(std::unique_ptr<MyBase> base) {
MyMiddle* derived = dynamic_cast<MyMiddle>(base.get());
if (derived == nullptr) {
// derived wasn't of the correct type, recover in a reasonable way.
return;
}
std::unique_ptr<MyMiddle> middle(derived);
// Here two unique_ptr own the same object, make sure not to throw exceptions!
base.release(); // Complete transfer of ownership.
SomethingThatNeedsTheNewFunction(middle); // Pass ownership of middle type.
}
Of course, std::unique_ptr does allow for custom deleters, which makes this whole setup way more fun. I recommend you read this answer for code that is propagating the deleter while constructing a unique pointer to a derived class. This only becomes necessary if your function signature allows for a non-standard deleter in its pointer argument.
You could do the above without the MyMiddle class, using two separate calls to dynamic_cast to try converting to each of your derived classes in turn. But as long as the middle class and the shared functionality makes sense conceptually I'd go for that. If you did two separate casts, then you could call a template function for both cases, and that template function could assume existence of that function even though it would be operating on different argument types. Doesn't feel like a great solution to me, though.
I feel like template specialization might be the way to go here but I'm not quite sure.
That would work if the caller would call the function with the actual derived type as the static type of the argument. So you could do
template <typename Base_t> void MyOperation(std::unique_ptr<Base_t> &base_object) {
// Handle the case where DoSomethingNew is not an option.
}
template <> void MyOperation(std::unique_ptr<MyAlpha> &alpha_object) {
alpha_object->DoSomethingNew();
}
template <> void MyOperation(std::unique_ptr<MyBeta> &beta_object) {
beta_object->DoSomethingNew();
}
But the following would still not call the specialized function:
std::unique_ptr<MyBase> object(new MyAlpha());
MyOperation(object);
Even though object dynamically contains a MyAlpha its static type is a unique pointer to MyBase, and that's what drives the template parameters. So I can't see a way where such a specialization would be useful to you.
dynamic_cast<> exists for when you need to either down cast or cross cast from your pointer-to-base into a derived class. In your example it would look something like this:
std::unique_ptr<MyBase> object = std::unique_ptr<MyAlpha>(new MyAlpha);
// ...
dynamic_cast<MyAlpha*>(object.get())->DoSomethingNew();
You can read more about it here, but as I mentioned in my comment, too many of these is an indicator you have a design problem. Especially here when you have that functionality in both derived classes, it could easily be moved into the base class.
As an alternative to dynamic_cast<> since you are unable to modify the base class, you could create your own base class where you inherit from the unmodifiable base class and customize the interface to something you will actually use.
class NewBase : public MyBase
{
public:
void DoSomething() = 0;
void DoSomethingNew() = 0;
};
std::unique_ptr<NewBase> object = std::unique_ptr<MyAlpha>(new MyAlpha);
// ...
object->DoSomethingNew();
I have a function like this:
void something(void *obj)
{
obj->Set();
}
The compiler says that left of the dereference operator has to be a pointer to a class/struct/union/generic (translated from german not sure about wording).
The idea is that I want to call the something function of obj no matter what is passed to something. It is ensured that it has this function. How can i achieve that?
--EDIT--
I started to work on an existing Software which has like > 100 Classes for datatypes. In one part of the code there is a big switch statement which depending on an id creates an instance of one of these classes and calls the Set function for that one. Now i want to do multiple of these calls parallel, and because of this i want to bring the ->Set() call to a seperate function which i then can call in a new thread. Sadly there is no baseclass and i cant change too much in the "big picture". What is the best way to do this?
C++ doesn’t allow this (for good reasons: even if you can ensure that the object always has a function, C++ cannot, and since you can make mistakes, C++ is justified in distrusting you).
The proper way to do this is to have a common base class which defined this method for all types that you want to use here, and then use this common base class as the argument of this function.
Alternatively, if it’s known at compile time which type is used here, then the appropriate implementation uses templates:
template <typename T>
void f(T const& obj) {
obj.something();
}
Whatever you do, void* is not appropriate. There are very rare legitimate use-cases for it in C++.
You need a base class or interface for whatever is passed into doSth:
class Base
{
public:
virtual void something() = 0; //override this in derived classes
}
doSth(Base* obj)
{
obj->something();
}
You can also cast the void* back to the original type:
doSth(void* obj)
{
((Base*)obj)->something();
}
but passing a void* as parameter suggests a faulty design. What exactly are you trying to achieve?
You need to implement pure virtual Base class with this function:
class Base
{
public:
virtual ~Base(){}
virtual void somefunction()=0;
}
class Derived1: public Base
{
public:
void somefunction()
{
//do something
}
}
class Derived2: public Base
{
public:
void somefunction()
{
//do something
}
}
And than use dynmic cast to get Base* from void*
doSth(void *obj)
{
Base *bobj=dynamic_cast<Base*>(obj);
if ( bobj )
bobj->somefunction();
}
Or mor simplier:
doSth(Base *obj)
{
obj->somefunction();
}
And usage is like:
Base *p1 = new Derived1();
Base *p2 = new Derived2();
doSth(p1); // cals somefunction in Derived1 class
doSth(p2); // cals somefunction in Derived2 class
The doSth method could take a function pointer as a parameter.
doSth( (*someFunc)() ) {
obj->*someFunc();
}
The call would look like:
doSth( &function );
When passing function pointers between different classes you should create a typedef for each function pointer and use qualifiers for each function identifier.
Just define an interface that lists all the functions of all the objects that you want to reference by the pointer, but the type of this pointer should not be void, but the name of this interface instead.
Then you will be able to call every function of every object that you want by this pointer, but make sure that all structures and classes of the objects implement all the functions of the interface!
This is also important to write the : public and then the name of the interface in the header of every structure and class!
I have one base class which holds a map for function pointers like this
typedef void (BaseClass::*event_t)();
class BaseClass {
protected:
std::map<std::string, event_t> events;
public:
// Example event
void onFoo() {
// can be added easily to the map
}
};
Handling this works prefect, but now i want to make BaseClass an abstract base class to derive from like this:
class SpecificClass : public BaseClass {
public:
void onBar() {
// this is gonna be difficult!
}
};
Although i can access the map from SpecificClass i am not able to add onBar because the event_t type is only defined for the BaseClass! Is there any possibility (maybe with templates?) which does not lead to define the event_t for each class i will use...
(It is not neccessary to use templates! Any good/suitable approach would be nice.)
More background information:
This whole thing is for a text based RPG. My base class could be called Location and the specifc one any location e.g. CivicCenter. Each Location object subscribes to my EventSystem which notifies all neccessary objects when i fire an event. Therefore i want to store in a map some pointers to private functions holding the actions with their "name" like onSetOnFire (xD) as the key.
This can't be done with your current map as it stands. Think about what would happen if you could put a child method into the map. Then you could pull a pointer-to-child-member (masquerading as base) out of the map, call it on a base class instance pointer, and then how would it call a derived class on a base class instance which obviously couldn't work.
Would a polymorphic approach work?
Yes; stop using member pointers.
The more correct way of doing what you want is to have an event type and an object pointer. So an event fires on a specific object. The event type would be a non-member function (or a static member). It would be passed the object pointer. And it would call some actual member function of that object.
Nowadays, the event type could be a std/boost::function. However, since the function parameters have to stay the same type for all events, this doesn't really fix your problem. You can't call SpecificClass::onBar from a BaseClass pointer unless you do a cast to a SpecificClass. And the event calling function would not know to do this. So you still can't put SpecificClass::onBar in the std/boost::function object; you still need some standalone function to do the cast for you.
This all just seems to be a terrible use of polymorphism. Why does SpecificClass need to derive from BaseClass at all? Can't they just be two unrelated classes?
You have to use static_cast:
event_t evt = static_cast<event_t>(&SpecificClass::onBar);
This is because it is slightly dangerous to cast to event_t, you could accidently apply it to a BaseClass instance.
How it works (for the skeptical):
class BaseClass {
public:
typedef void (BaseClass::*callback_t)(); // callback method
void doSomething(callback_t callback) {
// some code
this->*callback();
// more code
}
void baseCallback(); // an example callback
};
class DerivedClass : public BaseClass {
public:
void derivedCallback();
void doWhatever() {
// some code
doSomething(&BaseClass::baseCallback);
// more code
doSomething(static_cast<callback_t>(&DerivedClass::derivedCallback));
// et cetera
};
Here is what you should avoid, and why this is potentially dangerous:
void badCodeThatYouShouldNeverWrite()
{
BaseClass x;
// DO NOT DO THIS IT IS BAD
x.doSomething(static_cast<callback_t>(&DerivedClass::derivedCallback));
}
The requirement for a static_cast makes it so you can't "accidentally" pass DerivedClass method pointers in. And if you think this is dangerous, just remember that it's a pointer, and pointers are always dangerous. Of course, there are ways you can do this that involve creating helper classes, but that requires a lot of extra code (possibly making a class for every function you want to pass as a callback). Or you could use closures in C++11, or something from Boost, but I realize that a lot of us do not have that option.
After some thought and a redesign i was able to achieve what i wanted. Although i am stubborn and still using inheritance i have reimplemented the map. This is how it works now:
class Location {
// ...
protected:
std::map<std::string, std::function<void(void)>> m_mEvents;
};
And now i can handle it like this:
class CivicCenter : public Location {
public:
CivicCenter() {
// this is done by a macro which lookes better than this
this->m_mEvents["onTriggerSomething"] =
std::bind(&CivicCenter::onTriggerSomething, this);
}
void onTriggerSomething() {
// ...
}
// ...
};
With easy use of std::bind i am able to implement generic function pointers. When using parameters like in std::function<void(int, int)> remeber to use either boost's _1 and _2 or lambda expressions like me:
std::function<void(int,int)> f = [=](int a, int b) {
this->anotherFunctionWithParams(a, b);
};
But this is just pointed out due to completeness of my solution.
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.