我正在学习C ++,无法理解接口的工作方式。我已经建立了一个无效的小示例,并且我不明白自己做错了什么。
我已经阅读了this答案,这有助于我声明接口,但是(即使我仍然不完全理解该声明),现在我的关注点更多是关于用法。我也已经读过this答案,但是仍然不能使用我的界面,请参见以下示例:
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
}
构建此文件时,我得到:
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);
^
第二个错误使我感到困扰,因为在接口getArea()
中未实现Shape
正是我所期望的。第一个和第三个错误,我一点也不明白。我试图将主体更改为:
Weird shapeA = Weird(12);
Rectangle shapeB = Rectangle(2, 3);
但是从向量中抱怨allocating an object of abstract class type 'Shape'
的错误
我可能在这里错过了一些重要的事情,但是我有点卡住了...
EDIT:如注释中所建议,我在构造函数中使用了成员初始化列表,而不是向主体中的成员分配值。
答案 0 :(得分:7)
在C ++中,继承仅在具有指向对象的指针或引用时起作用。您不能拥有vector<Shape>
,因为Shape
不存在。我猜您是来自对象变量始终是引用(例如Java)的背景。
所以这是有效的
std::vector<Shape*> shapes;
shapes.push_back(new Rectangle(2, 3));
但是原始指针不是好的C ++。因此,最好使用某种智能指针
std::vector<std::shared_ptr<Shape>> shapes;
shapes.push_back(std::make_shared<Rectangle>(2, 3));
或
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Rectangle>(2, 3));