Search code examples
c++qtoopabstract-class

Declare an object as abstract class


Edit this question as originally posted was a simplified version of what I had and as such did not contain the problem which was causing the error. I have updated to be more like my problem, and will post an answer in case someone else has a similar issue.

In C++ is it possible to declare an object as an abstract class, but then instantiate it to a derived class?

Take this modified version of example code, gotten from https://www.tutorialspoint.com/cplusplus/cpp_interfaces.htm

class Shape {
   public:
      // pure virtual function providing interface framework.
      virtual int getArea() = 0;
      virtual int getNumOfSides() = 0;
      void setWidth(int w) {
         width = w;
      }
   
      void setHeight(int h) {
         height = h;
      }
   
   protected:
      int width;
      int height;
};
 
// Derived classes
class Rectangle: public Shape {
   public:
      int getArea() { 
         return (width * height); 
      }
};

class Triangle: public Shape {
   public:
      int getArea() { 
         return (width * height)/2; 
      }
};
 
int main(void) {
   Rectangle Rect;
   Triangle  Tri;
 
   Rect.setWidth(5);
   Rect.setHeight(7);
   
   // Print the area of the object.
   cout << "Total Rectangle area: " << Rect.getArea() << endl;

   Tri.setWidth(5);
   Tri.setHeight(7);
   
   // Print the area of the object.
   cout << "Total Triangle area: " << Tri.getArea() << endl; 

   return 0;
}

However, if we don't know the type of the Shape at compile time, is it possible to do something like:

Shape *shape;

if (userInput == 'R') {
   shape = new Rectangle();
} else if (userInput == 'T') {
   shape = new Triangle();
}

// etc.

... as can be done in C#?

I have tried that but got the error:

error: invalid new-expression of abstract class type 'Rectangle'

This is within QT.


Solution

  • The issue was that not all of the virtual functions defined by the abstract class were implemented in the derived classes.

    I needed

    // Derived classes
    class Rectangle: public Shape {
       public:
         int getArea() { 
            return (width * height); 
         }
         int getNumOfSides() {
            return 4;
         }
    };
    
    class Triangle: public Shape {
       public:
         int getArea() { 
            return (width * height)/2; 
         }
         int getNumOfSides() {
            return 3;
         }
    };