如何在 C++ 中为孙子级覆盖超类的虚函数? [英] How to make virtual functions of a super class overrideable for grandchildren in C++?

查看:34
本文介绍了如何在 C++ 中为孙子级覆盖超类的虚函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,这里有一些我将要运行的代码,问题是它没有按照我想要的方式工作.我无法弄清楚它有什么问题.我是 C++ 菜鸟,请帮忙.

Hey guys here is some code I am going to run, issue is it doesn't work the way I intend to. I am unable to figure out what's wrong with it. I am c++ noob please help.

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

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

I don't know why the array methods keep accessing the grand parent functions in the last three lines, but the right method on the first.

推荐答案

您正在体验对象切片.下面的代码部分就是这样做的:

You are experiencing Object Slicing. The portion of your code below does that:

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

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

Each of the assignments above invokes the copy assignment operator of Shape and slices off objects of the subclass. You can achieve your intention by using references or pointers:

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

这篇关于如何在 C++ 中为孙子级覆盖超类的虚函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆