c++ - 派生类的属性为空
问题描述
我是 C++ 新手,目前正在玩继承。我正在创建一个分别由 Rectangle 和 Triangle 类继承的基础 Polygon 类。从那里我想打印出calcArea
. 但是,我的派生类实例的输出似乎为空。
据我了解,这Polygon:(name, width, height)
可以帮助初始化基类中已经存在的变量。感谢所有的帮助!
这是我的代码:
#include <iostream>
#include <string>
using namespace std;
enum Polytype {POLY_PLAIN, POLY_RECT, POLY_TRIANG};
class Polygon
{
public:
Polygon(string name, double width, double height){
_name = name;
_width = width;
_height = height;
_polytype = POLY_PLAIN;
}
virtual ~Polygon()
{
cout << "Destroying polygon" << endl;
}
virtual Polytype getPolytype(){
return _polytype;
}
virtual void setPolytype(Polytype polytype){
_polytype = polytype;
}
virtual string getName(){
return _name;
}
virtual double calcArea(){
return _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle: public Polygon
{
public:
Rectangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_RECT;
};
~Rectangle()
{
cout << "Destroying rectangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
double calcArea(){
return _width * _height;
}
string getName(){
return _name;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype = POLY_RECT;
};
class Triangle: public Polygon
{
public:
Triangle(string name, double width, double height) : Polygon(name, width, height){
_polytype = POLY_TRIANG;
};
~Triangle()
{
cout << "Destroying triangle" << endl;
}
Polytype getPolytype(){
return _polytype;
}
void setPolytype(Polytype polytype){
_polytype = polytype;
}
string getName(){
return _name;
}
double calcArea(){
return 0.5 * _width * _height;
}
private:
string _name;
double _width;
double _height;
Polytype _polytype;
};
int main(){
//Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
cout << "Name is " << rect.getName() << endl;
cout << "Name is "<< triang.getName() << endl;
string rectArea = to_string(rect.calcArea());
string triangArea = to_string(triang.calcArea());
cout << "RectA's area is " << rectArea << endl;
cout << "TriangB's area is " << triangArea << endl;
return 0;
}
这是我的输出:
Name is
Name is
RectA's area is 0.000000
TriangB's area is 0.000000
Destroying triangle
Destroying polygon
Destroying rectangle
Destroying polygon
解决方案
主要问题是子类中的变量掩盖了基类中的名称 - 因此您将值分配给基类中的变量,但稍后您会打印子类中默认初始化变量的值。
您实际上主要需要删除代码。
不过,我会重新考虑基类的名称。Polygon
对于只有宽度和高度的类来说,这不是一个好名字。我会把它留给你。
我已经全部替换endl
为\n
. 他们做同样的事情,但endl
刷新输出,这通常是不需要的——但它通常也很昂贵。
例子:
#include <iostream>
#include <string>
enum Polytype { POLY_PLAIN, POLY_RECT, POLY_TRIANG };
class Polygon {
public:
Polygon(std::string name, double width, double height)
: Polygon(name, width, height, POLY_PLAIN) {}
virtual ~Polygon() { std::cout << "Destroying polygon\n"; }
// make member functions that does not change the object `const`:
virtual Polytype getPolytype() const { return _polytype; }
virtual void setPolytype(Polytype polytype) { _polytype = polytype; }
virtual const std::string& getName() const { return _name; }
// in your case, the implementation could actually be in the base class - but
// I've made it into a pure virtual here.
virtual double calcArea() const = 0; // no instances can be made of Polygon
protected:
// only derived classes can access this constructor:
Polygon(std::string name, double width, double height, Polytype ptype)
: _name(name), _width(width), _height(height), _polytype(ptype) {}
std::string _name;
double _width;
double _height;
Polytype _polytype;
};
class Rectangle : public Polygon {
public:
Rectangle(std::string name, double width, double height)
//use the protected base class ctor:
: Polygon(name, width, height, POLY_RECT) {};
~Rectangle() { std::cout << "Destroying rectangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return _width * _height; }
};
class Triangle : public Polygon {
public:
Triangle(std::string name, double width, double height)
: Polygon(name, width, height, POLY_TRIANG) {};
~Triangle() { std::cout << "Destroying triangle\n"; }
// the only implementation needed in this sub class:
double calcArea() const override { return 0.5 * _width * _height; }
};
int main() {
// Initialize rectangle and triangle and store them onto the stack
Rectangle rect("RectA", 10.0, 20.0);
Triangle triang("TriangB", 10.0, 20.0);
std::cout << "Name is " << rect.getName() << '\n';
std::cout << "Name is " << triang.getName() << '\n';
std::cout << "RectA's area is " << rect.calcArea() << '\n';
std::cout << "TriangB's area is " << triang.calcArea() << '\n';
}