派生的 类' 属性为空

Derived classes' attributes are empty

我是 C++ 的新手,目前正在研究继承。我正在创建一个基本多边形 class,它分别由矩形和三角形 classes 继承。从那里我想打印出 calcArea 中定义的区域。但是,我派生的 class 个实例的输出似乎为空。

据我了解,Polygon:(name, width, height) 可以帮助初始化已经存在于基 class 中的变量。感谢大家的帮助!

这是我的代码:

#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

主要问题是子 classes 中的变量隐藏了基 class 中的名称 - 因此您将值分配给基 class 中的变量,但是您稍后在子 classes.

中打印默认初始化变量的值

您实际上最需要删除代码。

不过,我会重新考虑基地的名称 class。 Polygon 对于只有宽度和高度的 class 来说不是一个好名字。我会把它留给你。

我已将所有 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';
}

我意识到我不必在我的子类中重新声明私有变量。这可能就是它返回 null 的原因。

#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;
        }

        ~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;
        }

    protected:
        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;
        }
};

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;
        }
};


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;
}