我有一个基类Shape,以及一个公共继承Shape的派生类Circle:
class Circle : public Shape
我制作了一个形状指针的C ++向量,并为它指定了Circle指针。我在对象切片上阅读了很多内容,因此我希望代码能够将向量中的圆视为圆形,而不是形状。
根据输出结果,有人能指出这个问题吗?
int main(void) {
vector<Shape*> shapes;
Circle* ncl = new Circle(-8, -8, 0.2f);
shapes.push_back(ncl);
cout << "Expected: " << *ncl << endl;
cout << "Reality: " << *shapes[0] << endl;
}
输出:
Expected: Circle is at: -8,-8 and has a radius of: 0.2
Reality: Shape centered at point: -8,-8
我已经覆盖了&lt;&lt;这两个类的运算符都超出了范围,所以我认为这不是问题,但仍然 - 这是我的覆盖的代码上下文:
inline std::ostream& operator<< (std::ostream& stream, const Shape& shape) {
std::cout << "Shape centered at point: " << shape.getX() << "," << shape.getY();
return stream;
}
inline std::ostream& operator<< (std::ostream& stream, const Circle& circle) {
std::cout << "Circle is at: " << circle.getX() << "," << circle.getY() <<
" and has a radius of: " << circle.getR();
return stream;
}
总而言之 - 我希望能够正确地访问我的Circle变量,同时将它们存储在Shape向量中(使用指针或其他方式)。
答案 0 :(得分:2)
没有涉及切片,它只是看起来像。
在编译时从编译器已知的静态类型中选择重载
由于shapes
是vector<Shape*>
,*shapes[0]
是Shape&
,并且选择了重载。
常见的解决方案是只为基类编写operator<<
,然后在对象上调用虚函数。
这将让动态函数dispatch在运行时选择函数。
例如:
struct Shape { virtual ostream& print(ostream& os) const { ... } };
struct Circle { ostream& print(ostream& os) const override { ... } };
ostream& operator<<(ostream& os, const Shape& s) { return s.print(os); }
答案 1 :(得分:1)
使用静态类型完成重载解析。
您可以使用:
std::ostream& operator<< (std::ostream& stream, const Shape& shape) {
shape.print(stream);
return stream;
}
使用virtual void Shape::print(std::ostream&) const;
解决您的问题。