Runtime introspection in C++ - c++

I have a class that looks like this:
class MyClass {
public:
void doSomething() { // nothing here };
}
and it also has a subclass that looks like this
class MyChildClass : MyClass {
public:
void doSomething() { // actual code here };
}
As you can see the doSomething() function does nothing in the parent class, but the child class overwrites it and adds actual code. My problem is that I am attempting to do something like this:
MyClass foo = MyChildClass();
foo.doSomething();
I was quite shocked to find that in this case, MyClass, and not MyChildClass's version of doSomething() is called, even though foo is actually of type MyChildClass. I have far more experience in Objective-C than C++ so this is very strange for me. It seems that C++ is determining which version of doSomething() needs to be called at compile-time, rather than inspecting the type of the object at run-time and calling the correct version.
This is problematic for me, because in my actual code what I have is one parent class and multiple different child classes that inherit from it. Each of these child classes overwrites the doSomething() function with their own unique implementation. I end up having an std::vector full of MyClass objects (which is really full of many different types of objects that each inherit from MyClass) and I want to loop through each of these object and invoke their version of doSomething() without actually knowing their type at compile-time. This would be easy in Objective-C, but is there any way for me to accomplish this in C++?

You need two things:
A reference or pointer to the created object, so that it isn't copy-sliced.
Having the member function virtual in the base class.
E.g., off the cuff,
struct MyClass{ virtual void foo() {} };
struct Derived: MyClass { void foo() override { /* ... */ } };
auto main() -> int
{
MyClass&& o = Derived{};
o.foo();
}
But why not just use the Derived type for the declaration?
” I end up having an std::vector full of MyClass objects (which is really full of many different types of objects that each inherit from MyClass) and I want to loop through each of these object and invoke their version of doSomething() without actually knowing their type at compile-time.
A vector<MyClass> slices each item to just the MyClass part. You can use a vector of pointers. If these are owning pointers, use a smart pointer like shared_ptr or unique_ptr.

If you want to run function based on run time information, you need to declare function as virtual function.

Related

Use derived class operations in function accepting pointer to abstract base class

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();

Inheritance without pointers

Suppose that I have a class with a single abstract virtual function like this:
class MyClass{
public:
virtual void MyFunc() = 0;
};
And I have no other functions, and no data members. I can also guarantee that all class which inherit from this do not have any data members and have no other functions except an implementation of MyFunc.
The biggest reason (at least in my mind) for forcing you to have a pointer to an abstract object is the size of the implementation is unknown....So is there a way to instead of having a pointer to this class just giving an instance (or pseudo instance) of the class. Take this for example:
void AFunction(MyFunc inst){ //Note the lack of pointer
inst.MyFunc(); //This should call the implementation
}
So is this even possible or am I just a wishful thinker?
You must pass either a pointer or a reference. You cannot pass by value, because that, by definition, involves making a copy of the value; and, by definition again, you can't copy an instance of an abstract class. C++ does not work this way.
So, take your pick, either:
void AFunction(MyFunc *inst){
inst->MyFunc();
}
or
void AFunction(MyFunc &inst){
inst.MyFunc();
}
Those are your options. Whether the subclasses have anything else, besides the virtual method implementation, or whether the abstract class has anything else, besides the virtual method, is irrelevant. The answer does not change.
It's not possible (without references or pointers).
class Interface {
public:
virtual void F() = 0;
};
class Implementation: public Interface {
public:
void F() {}
};
void SomeFunction(Interface x) {}
int main() {
Implementation impl;
SomeFunction(impl);
}
This is basically what you are suggesting. And if you were to compile this:
blah.cc:11:29: error: parameter type 'Interface' is an abstract class
void SomeFunction(Interface x) {}
^
You could use references, but that's basically just pointers with a different syntax.
void SomeFunction(Interface & x) {}
int main() {
Implementation impl;
SomeFunction(impl);
}
You could use std::function. You can pass it by-value without pointers but it acts like an interface for a function:
void AFunction(std::function<void()> myfunc){
myfunc(); //This will call the implementation
}
You could create this "interface" using a lambda:
MyClass mc;
auto myfunc = [mc]{mc.MyFunc();};
AFunction(myfunc);
Internally, std::function uses type erasure.
You could create your own wrapper that can be passed by value but you are probably going to need to use some sort of pointer internally.

Residing a member of parent class type inside another class

#include <iostream>
class BarParent
{
virtual void fuz()
{
std::cout << "BarParent" << std::endl;
}
};
class BarChild : public BarParent
{
virtual void fuz()
{
std::cout << "BarChild" << std::endl;
}
};
class Foo
{
// ??BarParent bar;??
public:
Foo(BarParent bar);
};
What I seek is to store a copy of BarParent that is passed to the constructor and let it reside in Foo, while still calling the correct virtual function
This is an embedded application: Use of the heap is frown upon. So preferably, no heap
SUMMARY: To the best of knowledge, it cannot be done, becuase of the slicing problem (long story short the compiler cannot determine the size of generic Bar and so on copying it type casts), so polymorphism cannot be achieved. Using templates might be a good idea, however, it defines multiple classes Foo<typename BarType>, as a result, doing a function such as changeBar(BarParent), would not be possible since the compiler would define this as changeBar(BarType) defined only for class Foo<Bartype>. If someone has a better idea, please let me know.
I think i will have to go for heap, or const Barparent and pointers. If the user const_casts, then he is asking for trouble, not my fault!
class Foo
{
BarParent* bar; //or std::unique_ptr<>
public:
Foo(BarParent* barInst):bar(barInst){}
};
This will do what you want it to. You store a pointer to a BarParent object and you can polymorphicaly(is that a word?) call virtual functions using it.
You need to create the copy outside the constructor (on the heap or otherwise), and pass the pointer to it to the foo object constructor. Alternatively you can implement a clone method as discussed at Copying derived entities using only base class pointers, (without exhaustive testing!) - C++
A radically different approach would be to use templates.. it would leave you with a multidudes of foo<> types though.. If you are not going to reassign the bar object, or store all foo in a container, this might be the better option for you, since it doesn't involve the heap
template<typename BarType>
class Foo
{
BarType bar; //pointer not needed any more since we are storing the exact type.
public:
Foo(BarType& barInst):bar(barInst){}
};
There is no way I know of to handle this gracefully without object slicing.
The only way I could think of would be to use pointer, and create a copy when "calling" the Foo constructor:
class Foo
{
BarParent* bar;
public:
Foo(BarParent* b) : bar(b) {}
};
BarChild child;
Foo myFoo(new BarChild(child));

Call a function of an object referenced by a void Pointer

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!

C++ member function pointers in class and subclass

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.