首页 > 解决方案 > 派生类的属性为空

问题描述

我是 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

标签: c++inheritance

解决方案


主要问题是子类中的变量掩盖了基类中的名称 - 因此您将值分配给基类中的变量,但稍后您会打印子类中默认初始化变量的值。

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

不过,我会重新考虑基类的名称。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';
}

推荐阅读