Search code examples
c++pointerspolymorphismc++17derived-class

C++ function resolving base class pointer to derived class pointer


I tried implement something similar to JSON with pointers as a part of an exam question, and I ended up with an error that I didn't know how to solve.

I had these classes (leaving out the implementation, because I don't think it is important for my error):

struct JSON_BaseObject;

template<typename J_Type>
struct JSON_Value : public JSON_BaseObject;

struct JSON_String : public JSON_Value<std::string>;
struct JSON_Number : public JSON_Value<double>;
struct JSON_Null : public JSON_BaseObject;

using JSON_Children = std::map<std::string, JSON_BaseObject*>;
using JSON_Object = JSON_Value<JSON_Children>;

And I wanted to use the children of type JSON_BaseObject* in JSON_Object as a parameter to functions that had different overloads for these derived types, so I made these functions and hoped that they would resolve JSON_BaseObject* to the respective class (pointer):

void print(JSON_Null*, std::ostream& os);
void print(JSON_String* str, std::ostream& os);
void print(JSON_Number* number, std::ostream& os);
void print(JSON_Object* object, std::ostream& os);

When I ran it, I got a run-time error that the program wasn't able to find the function print(JSON_BaseObject*, std::ostream&) and I realized that I wasn't as good at c++ as I thought I was.

Question 1

Is it possible to resolve pointer type parameters from a baseclass like this somehow?

Question 2

How can I make it nice e.g. begin able to use print(obj, os); without knowing the derived class of obj?


Solution

  • After trying out the visitor pattern I realized that it solves all my problems. It also resolves the base pointers in an easy way.

    It enabled a nice code like this:

    int main()
    {
        JSON_Object obj = JSON_Object();
        JSON_String str = JSON_String("I am a string!");
    
        std::vector<JSON_Base*> basePtrs
        {
            &obj,
            &str
        };
    
        Printer printer;
    
        for (auto json : basePtrs)
        {
            json->PrintMe(printer);
        }
    }