alam
alam

Reputation: 11

How to declare an "unknown" derived class as base class as a member and allow the derived version of member function to be called?

I am currently trying to set a member of a class (myClass) to be some derived classes (Derived1, Derived2,...) of a Base class. Since the class don't know which derived class it is, the member type is set to Base class, it is only set to the derived class when constructed.

The derived classes all have a common member function which is implemented differently (Base class has a virtual version). However, when the this function is called from myClass, it always call the Base class version rather than the derived classes.

class Base
{
public:
    Base(){}
    virtual void who() { cout << "this is Base"; }
}

class Derived1 : public Base
{
public:
    Derived1() : Base() {}
    void who() { cout << "this is Derived1"; }
}

class myClass
{
private:
    Base unknownDerived;
public:
    myClass(const Base& inputDerived) { unknownDerived = inputDerived; }
    void whosthere() { unknownDerived.who(); }
}

The output above is "this is Base", the Base class version is called instead.

Is there a way to include a member without specifying the actual derived class it is, but be able to call its specific function ( who() )?

thanks a lot!

Upvotes: 1

Views: 303

Answers (1)

Chris Uzdavinis
Chris Uzdavinis

Reputation: 6131

When you declare Base as a member, Base is what you actually get. Even if you assign a Derived type to it, you experience what's called "slicing", where only the Base part of the derived object is copied, and your object is still a Base.

In C++, polymorphism only works through pointers and through references.

To make a real member object (not an indirection to the object) in myClass, you will need to make myClass have a template parameter, and you can decide at compile time what type it will be. Otherwise, you must use pointers and/or references.

Now you have to be clear about memory ownership, and proper cleanup. You may make the caller transfer the ownership of the object (by taking a unique_ptr) or you might insist that Base has a virtual clone() function to create a deep copy of the object. Further, you most likely will need a virtual destructor in your base class as well.

Upvotes: 4

Related Questions