Search code examples
c++inheritancepolymorphismabstract-classvirtual-functions

How to make polymorphic field of class in C++? How to use polymorphism correctly in this case?


I have a class

class A 
{
    BasePtr * ptr;
    virtual BasePtr * getPtr() { return ptr; }
    virtual void pure() = 0;
}

And I want to derive two classes from it that create its own versions of ptr:

class B : public A 
{
    B() : A() { ptr = new RoundPtr(); }
};

class C : public A 
{
    C() : A() { ptr = new SquarePtr(); }
}

Then I create a list of pointers to basic class:

A * list[2];
list[0] = new B();
list[1] = new C();

And call this method:

list[i]->getPtr();

But I found that it returns an uninitialized pointer.

So, how to correctly use polymorphism here? How to properly create this field to use different types of it?


Solution

  • Ok, I tested this code and it works perfectly o_0 But I got crashed in more complex program when try to call method of polymorphic object pointer. Maybe I have an additional errors in my project.

    The answer is:

    #include <iostream>
    
    class Ptr {
        public:
            Ptr(int x, int y) : centerX(x), centerY(y) {}
            virtual ~Ptr() {}
            virtual void foo() = 0;
    
        protected:
            int centerX, centerY;
    };
    
    class RoundPtr: public Ptr {
        public:
            RoundPtr(int x, int y, int radius) : Ptr(x, y), circleRadius(radius) {}
            virtual void foo() { std::cout << "RoundPtr, x: " << centerX << ", y: " << centerY << ", radius: " << circleRadius << std::endl; }
    
        protected:
            int circleRadius;
    };
    
    class SquarePtr: public Ptr {
        public:
            SquarePtr(int x, int y, int w, int h) : Ptr(x, y),
                leftX(centerX - w/2), leftY(centerY - h/2),
                width(w), height(h)
                {}
    
            virtual void foo() { std::cout << "SquarePtr, x: " << centerX << ", y: " << centerY << ", leftX: " << leftX << ", leftY: " << leftY << ", width: " << width << ", height: " << height << std::endl; }
    
        protected:
            int leftX, leftY;
            int width, height;
    };
    
    class A {
        protected:
            Ptr * ptr;
    
        public:
            A() : ptr(nullptr) {}
            virtual ~A() {}
    
            virtual Ptr * getPtr() { return ptr; }
    };
    
    class B : public A {
        public:
            B() : A() { ptr = new RoundPtr(0, 0, 10); }
            virtual ~B() { delete ptr; }
    };
    
    class C : public A {
        public:
            C() : A() { ptr = new SquarePtr(5, 5, 10, 10); }
            virtual ~C() { delete ptr; };
    };
    
    int main()
    {
      A * bObj = new B();
      A * cObj = new C();
    
      bObj->getPtr()->foo();
      cObj->getPtr()->foo();
    
      delete bObj;
      delete cObj;
    }
    

    Can anybody check this code? Do you see any problems with it? Is it good solution? Is it possible to use smart pointers from c++11 here?