对一个类成员进行重写并不会覆盖基类成员
我在尝试解决一个练习,但在我的最后一个 toString() 上一直遇到错误,我不明白问题出在哪里。
#include <iostream>
using namespace std;
class Shape
{
protected:
string color;
bool filled;
public:
Shape() {
color = "white";
filled = false;
}
Shape(string c, bool f)
{
color = c;
filled = f;
}
string toString() {
return "Shape[color= " + color + "filled = " + (filled ? "true" : "false") + "]";
}
double getArea = 0;
};
class Rectangle : public Shape
{
protected:
double width;
double height;
public:
Rectangle() {
width = 1.0;
height = 1.0;
}
Rectangle(string c, bool f, double w, double h) :Shape(c , f) {
width = w;
height = h;
}
string toString() const override {
return "Rectangle[width = " + width + "height = " + height + "]";
}
};
在第49行,编译器给出如下错误:
我被要求做以下工作:
覆写toString() 方法,以以下格式显示矩形信息:
Rectangle[width=..., height=..., Shape[color=..., filled=...]]。
但,编译器似乎对我返回宽度的方式不满意。
解决方案
你的代码中有几个问题:
- 为了
override方法toString在Rectangle中:
(1) 它必须在基类Shape中被标记为virtual。
(2) 它必须与Shape中的签名相同——因此要么两者都为const,要么两者都不是。
请注意,Shape::toString 默认不是虚拟的,只要是这样,Rectangle::toString 只能隐藏而不能覆盖它。
2.你不能随意将不同类型拼接在一起以创建一个 std::string。如果第一个是一个 std::string,且其余可以转换成同一类型,那么效果会比较好(并且 double,例如 width,不是)。你可以使用 std::to_string(支持的类型)。
一个可行的修复方法用于 Rectangle::toString:
return std::string("Rectangle[width = ") + std::to_string(width) + "height = " + std::to_string(height) + "]";
注:有时,例如在 Shape::toString,你可以省略对 std::string 的第一次显式转换。但保留它会让代码更安全,例如如果 color 的类型改为 int(并且与 Rectangle::toString 更一致)。
3.在构造函数中,最好通过 const& 接受 std::string 参数,以避免拷贝。
4.不建议添加 using namespace std;。
参见:What's the problem with "using namespace std;"?.
修正版:
#include <iostream>
#include <string>
class Shape
{
protected:
std::string color;
bool filled;
public:
Shape() {
color = "white";
filled = false;
}
Shape(std::string const & c, bool f) {
color = c;
filled = f;
}
virtual std::string toString() const {
return std::string("Shape[color= ") + color + "filled = " + (filled ? "true" : "false") + "]";
}
};
class Rectangle : public Shape
{
protected:
double width;
double height;
public:
Rectangle() {
width = 1.0;
height = 1.0;
}
Rectangle(std::string const & c, bool f, double w, double h) :Shape(c , f) {
width = w;
height = h;
}
std::string toString() const override {
return std::string("Rectangle[width = ") + std::to_string(width) + "height = " + std::to_string(height) + "]";
}
};
Live demo
