简体   繁体   English

继承和纯虚函数

[英]Inheritance and Pure virtual functions

I'm learning inheritance in c++, and I'm new to abstract pure virtual, base, and derived classes. 我正在学习c ++中的继承,而且我是抽象纯虚拟,基类和派生类的新手。 So I came up with this below code, it works but I'm not sure if I'm implementing the c++ principals correct. 所以我想出了下面的代码,它可以工作,但我不确定我是否正在实现c ++主体。 Please can someone evaluate the below code for improvement. 请有人评估以下代码以求改进。

#include <iostream>
using namespace std;

class Pizza
{
   private:
       double pCost;
       double pPrice;

   public:
       Pizza(const double& c, const double& p) : pCost(c), pPrice(p){}
       virtual ~Pizza(){}
       virtual double area() = 0;
       virtual double cost() = 0;
       virtual double price () = 0;
       virtual double profit() = 0;
       double getCost() const {return pCost;}
       double getPrice() const {return pPrice;}
};

class CircularPizza : public Pizza
{
   private:
       double radius;

   public:
       CircularPizza(const double& r, const double& c, const double& p)
        : Pizza(c, p), radius(r){}
        virtual ~CircularPizza(){}
        virtual double area(){ return (3.14 * radius * radius);}
        virtual double cost() { return area() * getCost(); }
        virtual double price() { return area() * getPrice(); }
        virtual double profit() { return price() - cost();}
};

If I were to change anything, I'd make cost(), price() and profit() be non-virtual and define them in the base Pizza class. 如果我要改变任何东西,我会将cost(), price()profit()设为非虚拟,并在基础Pizza类中定义它们。

This makes sense because they all depend on area -- that's the only thing that CircularPizza is really defining. 这是有道理的,因为它们都依赖于区域 - 这是CircularPizza真正定义的唯一东西。 If you were to make a RectangularPizza class, the cost per area, the price per area, the calculation of profit would be the same. 如果您要制作RectangularPizza类,则每个区域的成本,每个区域的价格,利润的计算将是相同的。 The only thing that would change would be the area itself. 唯一可能改变的是该地区本身。 Realising this fact is what should lead you to design the classes in the same way, where only the area changes and other code is common to both CircularPizza and RectangularPizza using a base class. 实现这一事实应该导致您以相同的方式设计类,其中只有区域更改,而其他代码对于使用基类的CircularPizzaRectangularPizza都是通用的。

That's looking okay... However, it's strange to have a getCost() method as well as cost() . 看起来没问题......然而,拥有一个getCost()方法以及cost()是很奇怪的。 Same with price... If the whole point of the cost and price functions is to be implementation-specific, then providing access to the internal pCost and pPrice members doesn't seem right. 与价格相同......如果成本和价格函数的整个点是特定于实现的,那么提供对内部pCostpPrice成员的访问似乎并不正确。

Perhaps it's just a naming thing? 也许这只是一个命名的事情? Since you provide a cost and price in the constructor it's fair enough to be able to query these later. 由于您在构造函数中提供了成本和价格,因此可以在以后查询这些内容。 So in that case, there's a semantic problem (in my eyes anyway) with the names of the cost() and price() members. 所以在这种情况下,使用cost()price()成员的名称存在语义问题(无论如何在我看来price() Or perhaps what you mean is something like "unit cost" and "total cost". 或许你的意思是“单位成本”和“总成本”。

You may want to consider making the member variables protected instead of private. 您可能需要考虑使成员变量受保护而不是私有。

In terms of your C++ it all looks okay, except possibly those virtual functions should be constant if they do not modify the class (that way they can be called on a const instance of the class). 就你的C ++而言,它们都看起来没问题,除非这些虚函数可能在不修改类时应该是常量(这样它们可以在类的const实例上调用)。

Also, for completeness you may want to implement a function CircularPizza::getRadius() to be consistent with functions provided by the Pizza class. 此外,为了完整性,您可能希望实现一个函数CircularPizza::getRadius()以与Pizza类提供的函数一致。

For homework, looks fine. 对于家庭作业,看起来很好。 For additional reading consider this on when to use private virtual functions . 有关其他阅读,请考虑何时使用私有虚拟功能 Additionally I find it's helpful to occasionally create interfaces , similar to C#. 另外我发现偶尔创建类似于C#的接口是有帮助的。

值得一提的另一点是,CircularPizza对象中的area(),cost(),price()和profit()函数不需要是虚拟的,除非您打算将CircularPizza用作另一个派生类的基类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM