Reputation: 546
I'm learning C++, I have trouble understanding how interfaces work. I've set up a small example which doesn't work, and I don't understand what I've done wrong.
I've read this answer, which helped me declaring the interface, but (even if I still don't understand fully the declaration) my concern right now is more about the usage. I've read this answer too, but still, I can't use my interface, see this example :
shape.h
#ifndef SHAPE_H
#define SHAPE_H
class Shape
{
public:
virtual ~Shape(){}
virtual int getArea() = 0;
};
#endif // SHAPE_H
rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include "shape.h"
class Rectangle : public Shape
{
public:
Rectangle(){}
Rectangle(int w, int h) : width{w}, height{h} {}
virtual int getArea();
private:
int width = 0;
int height = 0;
};
#endif // RECTANGLE_H
rectangle.cpp
#include "rectangle.h"
int Rectangle::getArea()
{
return width * height;
}
weird.h
#ifndef WEIRD_H
#define WEIRD_H
#include "shape.h"
class Weird : public Shape
{
public:
Weird(){}
Weird(int a) : area(a){}
virtual int getArea();
private:
int area = 0;
};
#endif // WEIRD_H
weird.cpp
#include "weird.h"
int Weird::getArea()
{
return area;
}
main.cpp
#include <cstdio>
#include <vector>
#include "shape.h"
#include "weird.h"
#include "rectangle.h"
int main(void)
{
std::vector<Shape> shapes;
Shape shapeA = Weird(12);
Shape shapeB = Rectangle(2, 3);
shapes.push_back(shapeA);
shapes.push_back(shapeB);
int total = 0;
for(auto&& s : shapes)
{
total += s.getArea();
}
printf("%d\n", total); //Would expect 18
}
When I build this, I get :
main.cpp:11:9: error: variable type 'Shape' is an abstract class
Shape shapeA = Weird(12);
^
./shape.h:8:18: note: unimplemented pure virtual method 'getArea' in 'Shape'
virtual int getArea() = 0;
^
main.cpp:12:9: error: variable type 'Shape' is an abstract class
Shape shapeB = Rectangle(2, 3);
^
The second error bothers me, because not implementing getArea()
in the Shape
class is precisely what I'm expecting from an interface. The first and third errors, I don't understand at all. I tried to change the main to :
Weird shapeA = Weird(12);
Rectangle shapeB = Rectangle(2, 3);
But got errors from the vector complaining about allocating an object of abstract class type 'Shape'
I'm probably missing a few important things here, but I'm a bit stuck...
EDIT : As suggested in comments, I used member initialization lists in constructors instead of assigning values to members in the body.
Upvotes: 0
Views: 114
Reputation: 87959
In C++ inheritance only works when you have pointers or references to an object. You cannot have a vector<Shape>
because Shape
can't exist. I'm guessing you come from a background where object variables are always references (like Java).
So this is valid
std::vector<Shape*> shapes;
shapes.push_back(new Rectangle(2, 3));
but raw pointers are not good C++. So some sort of smart pointer is preferable
std::vector<std::shared_ptr<Shape>> shapes;
shapes.push_back(std::make_shared<Rectangle>(2, 3));
or
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Rectangle>(2, 3));
Upvotes: 7