Search code examples
c++classoopcompiler-constructionderived-class

Derived class members inaccessible from within a function that takes pointer to base class as parameter?


I am implementing type checking and wrote a function that takes two pointers to base class objects and checks whether the objects represent the same type of not.

This is the base class definition:

class Type {
public:
    virtual int get_type(void) { return 1; };
    string name;
    Type(){};
    Type(string n)
    {
        name = n;
    }
};

Currently, I have one derived class which is given below:

class Array : public Type {
public:
    Type *type;
    int depth;
    virtual int get_type(void) { return 3; };
    Array(Type *t, int d) : Type("array"){
        type = t;
        depth = d;
    }
};

The function I've written is as follows:

bool check_type(Type *t1, Type *t2)
{
    int a1 = t1->get_type(), a2 = t2->get_type();
    if (a1 != a2)
        return false;
    if(a1 == 1 )
    {
        if(t1->name == t2->name)
            return true;
        return false;
    }
    else if(a1 == 3)
    {
        if(t1->depth == t2->depth && check_type(t1->type, t2->type))
            return true;
        return false;
    }
}

As you can see the function checks if two objects are same or not.

When accessing derived class members depth and type from within the function I get the following error:

./src/parser.y:722:29: error: ‘class Type’ has no member named ‘depth’
         if(t1->depth == t2->depth && check_type(t1->type, t2->type))
                             ^
./src/parser.y:722:53: error: ‘class Type’ has no member named ‘type’
         if(t1->depth == t2->depth && check_type(t1->type, t2->type))
                                                     ^

I am new to C++ classes. Why am I getting this error and how else can I implement what I'm trying to do here?

Edit: I changed a part of the code to

Array *ar1 = dynamic_cast<Array*>(t1);
Array *ar2 = dynamic_cast<Array*>(t2);
if(ar1->depth == ar2->depth && check_type(ar1->type, ar2->type))
     return true;

and the issue was resolved.


Solution

  • It is because, in the eyes of the compiler, both t1 and t2 are pointers to "Type" and the class "Type" does not have any members named "depth" and "type". The compiler does not know that the original class is "Array". I understand that as per your logic, if(a1 == 3) then the type of the class is "Array". But the compiler does not know that.

    Now the question is how to solve it. I am not sure what you are actually trying to achieve with these classes. But with the current knowledge of your problem, I can only give you the below solution.

    On reaching this statement (which has the compilation error), since we are sure that the type of t1 and t2 is "Array", we can actually dynamically cast those to a type Array* and then access the member variables type and depth.

    Array* arrT1 = dynamic_cast<Array*> (t1);
    Array* arrT2 = dynamic_cast<Array*> (t2);
    

    Now you can access the depth and type as arrT1->depth and arrT1->type (or arrT2->depth, arrT2->type) as below

    if(arrT1->depth == arrT2->depth && check_type(arrT1->type, arrT2->type))
            return true;