Search code examples
c++arraysparent-childsubclassbase-class

How to store a pointer to SubClass object in a BaseClass pointer array?


I am trying to create a BaseClass array that stores SubClass objects. Below are the follow steps I use to do this:

  1. I create a BaseClass array.
  2. I create a new SubClass object to be stored in the array.
  3. I call the printSelf() function of that object in the array.
  4. The method incorrectly calls the BaseClass function, not the SubClass function.

The error here is that the object stored in the BaseClass array is of a BaseClass object. I need it so that the BaseClass array stores an object of type SubClass.

The problem is designed such that if there were to be multiple SubClasses (i.e. SubClassA, SubClassB, SubClassC...) they would all be stored in a single array.

I've tried various other solutions on StackOverFlow. None so far have provided a solution as to why creating a SubClass object will not store its class type properly in a BaseClass array.

class BaseClass {
    public: void printSelf() { cout << "This element is a BaseClass." << endl; };
};

class SubClass : public BaseClass {
    public: void printSelf() { cout << "This element is a SubClass." << endl; };
};

class House {
    public: House();
    private: BaseClass* subClassArray[1];
};

House::House() {
    subClassArray[0] = new SubClass;
    subClassArray[0]->printSelf();
}

int main() {
    House houseMain;
}

I expect the output to be "This element is a SubClass."

Instead, the output I am receiving is "This element is a BaseClass."


Solution

  • You need to declare printSelf as virtual. In addition you almost certainly want to add a virtual destructor to your class.

    class BaseClass {
        public: virtual void printSelf() const { cout << "This element is a BaseClass." << endl; };
                ////// <- must           ///// <- recommended
                virtual ~BaseClass() = default; // <-- HIGHLY recommended
    };
    
    class SubClass : public BaseClass {
        public: void printSelf() const override { cout << "This element is a SubClass." << endl; };
                                       //////// <- recommended
    };
    

    The following line is twice problematic.

    private: BaseClass* subClassArray[1];
    

    First, it is using raw C-style pointers. Second, it uses a raw C-style array. Both are not recommended in today's C++ development. You want to read about smart pointers, std::vector and std::array.

    Do NOT use any casts here, this is a non-option.