Retrieve Child Derived Data Through Parent Base Data Pointer C++

Viewed 54

I'm trying to design a hierarchy where derived classes containing a derived data type inherit from base classes containing a base data type, while exposing the functionality to retrieve children data polymorphically.

E.g. What I would like to do:

BaseClass* base = new BaseClass();
cout<< "base data: " << base->get_data()->my_base_str << '\n';

BaseClass* derived = new DerivedClass();
cout << "derived data: " << derived->get_data()->my_derived_int << '\n';

I have tried to return a pointer to the base data type and access the derived data members through said pointer, but of course the pointer isn't aware of the existence of the derived data members (nor should it be).

e.g.

class BaseDataType{
    public:
        BaseDataType() : my_base_str("base string"){}
        virtual ~BaseDataType() = default;
        std::string my_base_str;
};

class DerivedDataType : public BaseDataType{
    public:
        DerivedDataType() : my_derived_int(18){}
        int my_derived_int;
};

class BaseClass{
    public:
        virtual BaseDataType* get_data(){
            return &base_data;
        };
    private:
        BaseDataType base_data;
};

class DerivedClass : public BaseClass{
    public:
    BaseDataType* get_data() override{
        return &derived_data;
    }
    private:
    DerivedDataType derived_data;
};

And of course I get the error:

error: ‘class BaseDataType’ has no member named ‘my_derived_int’

Is there a way to achieve what I am trying to do here?

1 Answers

I really do not recommend to do this, but if you have access to c++17, then you can have virtual function in BaseDataType, returning std::any

class BaseDataType{
    public:
        BaseDataType() : my_base_str("base string"){}
        virtual ~BaseDataType() = default;
        virtual std::any get_data_any() const
        {
            return std::any(my_base_str);
        }
        std::string my_base_str;
};

class DerivedDataType : public BaseDataType{
    public:
        DerivedDataType() : my_derived_int(18){}
        virtual std::any get_data_any() const
        {
            return std::any(my_derived_int);
        }
        int my_derived_int;
};

class BaseClass{
    public:
        virtual BaseDataType* get_data(){
            return &base_data;
        };
    private:
        BaseDataType base_data;
};

class DerivedClass : public BaseClass{
    public:
    BaseDataType* get_data() override{
        return &derived_data;
    }
    private:
    DerivedDataType derived_data;
};

If you don't have access c++17, there is also boost::any. And I feel the urge to state again that I really do not recommend this.

Here is demonstration of using the function.

BaseClass* base = new BaseClass();
std::string str = std::any_cast<std::string>(base->get_data()->get_data_any());

BaseClass* derived = new DerivedClass();
int i = std::any_cast<int>(derived->get_data()->get_data_any());

std::cout << str << i;
Related