2

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++?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Christian Daley
  • 779
  • 2
  • 9
  • 13

2 Answers2

6

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.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Thank you! I made the function virtual in the parent's header file and also used a vector of pointers instead of the objects directly. I didn't know that std::vector slices the classes like that. My code works as expected now, thanks alot! – Christian Daley Apr 20 '18 at 05:45
2

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

code707
  • 1,663
  • 1
  • 8
  • 20