c++ - 如何在 C++ 中使父类(super class)的虚函数可被孙子覆盖?

标签 c++ c++11 abstract-class virtual-functions

<分区>

大家好,这是我要运行的一些代码,问题是它没有按照我的预期运行。我无法弄清楚它有什么问题。我是 C++ 菜鸟,请帮忙。

#include <iostream>
#include <cmath>
#include <stdexcept>
using namespace std;

/**
 * Super class
 */
class Shape
{
protected:
    int _dimensions;
public:
    Shape() : _dimensions{0}
    {};
    Shape(int dims) : _dimensions{dims}
    {};

    virtual double getArea() {};
    // Because some shapes have no volume.  
    virtual double getVolume() {};  

    void setDimensions(int dim)
    {
        this->_dimensions = dim;
    };
    int getDimensions()
    {
        return this->_dimensions;
    };
};


/** 
 * Extended classes
 */
class TwoDimensionalShape : public Shape
{
public: 
    TwoDimensionalShape() : Shape{2}
    {};
    // This should throw an error
    double getVolume() {
        throw logic_error("This shape ain't got area!");
    };  
};

class ThreeDimensionalShape : public Shape
{
public: 
    ThreeDimensionalShape() : Shape{3} {};
};


/**
 * Final Concrete classes extending extended classes
 */
class Circle : public TwoDimensionalShape
{
protected:
    double _radius;
public:
    Circle(double r) : _radius{r}
    {};
    double getArea()
    {
        // pi*r^2
        return M_PI * pow(_radius, 2);
    }
};

class Square : public TwoDimensionalShape
{
protected:
    double _side;
public:
    Square(double s) : _side{s}
    {}
    double getArea()
    {
        // s^2
        return pow(_side, 2);
    }
};

class Triangle : public TwoDimensionalShape
{
protected:
    double _base, _height;
public:
    Triangle(double b, double h) : _base{b}, _height{h}
    {};
    double getArea()
    {
        // b*h/2
        return _base * _height / 2;
    }
};

class Sphere : public ThreeDimensionalShape
{
protected:
    double _radius;
public:
    Sphere(double r) : _radius{r}
    {}
    double getArea()
    {
        cout << 4 * M_PI * pow(_radius, 2) << endl;
        return 4 * M_PI * pow(_radius, 2);
    }
    double getVolume()
    {
        return (4/3) * M_PI * pow(_radius, 3);
    }
};

class Cube : public ThreeDimensionalShape
{
protected:
    double _side;
public:
    Cube(double s) : _side{s}
    {};
    double getArea()
    {
        // surface area = 6*a^2
        return 6 * pow(_side, 2);
    }
    double getVolume()
    {
        // a^3
        return pow(_side, 3);
    }
};

class Tetrahedron : public ThreeDimensionalShape
{
protected:
    double _side;
public:
    Tetrahedron(double s) : _side{s}
    {};
    double getArea()
    {
        // sqrt(3)*a^2
        return sqrt(3) * pow(_side, 2);
    }
    double getVolume()
    {
        // a^3/6sqrt(2)
        return pow(_side, 3) / (6 * sqrt(2));
    }
};

int main()
{
    Shape arr[2];
    arr[0] = Circle{10};
    arr[1] = Sphere{10};

    // This one is accessing the right method.
    cout << "Area of circle: " << arr[0].getArea() << endl; 
    // This one should access the parent, but accesses the grand parent!
    // even if it is overridden in parent.
    cout << "Volume of circle: " << arr[0].getVolume() << endl; 

    // Both of these are accessing methods on grand parent rather than their own!!
    cout << "Area of sphere: " << arr[1].getArea() << endl;
    cout << "Volume of sphere: " << arr[1].getVolume() << endl; 

    return 0;
}

我不知道为什么数组方法在最后三行中继续访问祖父函数,但第一行是正确的方法。

最佳答案

您正在经历对象切片。下面的代码部分执行此操作:

Shape arr[2];
arr[0] = Circle{10};
arr[1] = Sphere{10};

上面的每个赋值调用Shapeslices 的复制赋值运算符关闭子类的对象。您可以通过使用引用或指针来实现您的意图:

std::unique_ptr<Shape> arr[2];
arr[0] = std::make_unique<Circle>(10);
arr[1] = std::make_unique<Sphere>(10);

关于c++ - 如何在 C++ 中使父类(super class)的虚函数可被孙子覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44343888/

相关文章:

c++ - 如何删除超过 1 个指向同一地址的指针

c++ - 非阻塞套接字,即使没有明确将它们设置为非阻塞

c++ - cmake 在 macOS 下构建 llvm/clang 时出错

c++ - 使用继承构造函数时 VS2015 内部编译器错误

c++ - 静态 __forceinline 或 __forceinline 静态

java - 具有单例模式和静态方法和变量的多个子类

c# - 是否可以在继承类中覆盖抽象父类的嵌套类定义?

c++ - 调试断言仅在某些情况下失败? C++

Linux 四核 : single executable, 4 个进程

c# - 在 C# 中,有没有办法让类使用接口(interface)或抽象类定义字段?