我试图理解 is-a 与 is-like-a 的关系,我在某处读到我们必须尝试遵循设计,以便我们始终拥有 is-like-a 关系而不是 is-like-a。考虑形状基类和派生的三角形和圆形类的经典示例。所以圆是一种形状,三角形也是一种形状。功能显示区定义在基类中。现在下面的程序运行正常。
#include "stdafx.h"
#include <cmath>
#include <iostream>
class shape
{
public:
virtual void displayArea()=0;
};
class circle :public shape
{
int radius;
public:
circle(int radius2) :radius(radius2){ }
void displayArea()
{
double area = 3.14*radius*radius;
std::cout << " \n Area circle" << area<<std::endl;
}
};
class triangle :public shape
{
double a,b,c;
public:
triangle(double a1, double b1, double c1): a(a1), b(b1),c(c1)
{
if (a + b > c && a + c > b && b + c > a)
std::cout << "The sides form a triangle" << std::endl;
else
std::cout << "The sides do not form a triangle. Correct me !" << std::endl;
}
void displayArea()
{
double s = (a + b + c) / 2;
double area = sqrt(s*(s - a)*(s - b)*(s - c));
std::cout << " \n Area triangle"<< area<<std::endl;
}
};
void main()
{
shape * p1[2];
p1[0]= new circle(20);
p1[1] = new triangle(5.6,8.1,10.3);
for (int i = 0; i < 2; ++i)
{
p1[i]->displayArea();
}
int y;
std::cin >> y;
}
现在,如果需要实现 modifyShape
函数,其中形状的每个参数都根据用户的参数进行修改,那么我应该如何更改我的类,使我的 is-a 关系没有改变。当我看它时,我觉得我必须在圆圈中定义一个参数 modifyShape
并在三角形中定义一个 3-argument modifyShape
。但是这个函数在基类中应该是什么样子呢?
选项 1:我在形状中定义了单个参数和两个参数 modifyShape
函数,但这意味着我将在圆形中有一个额外的 2 个参数函数,在三角形中有一个额外的 1 个参数函数。
选项 2:我在 shape 中定义了一个可变参数函数 modifyShape
,但不知何故这对我来说看起来并不清晰。
最佳答案
您可以使用第三个选项,您可以创建一个新的类层次结构 (或结构)将代表每个形状的参数。然后你可以通过 指向基类的指针作为虚函数的参数。 例如:
struct ShapeParams
{
...
}
struct TriangleParams : public ShapeParams
{
double a;
double b;
double c:
}
class shape
{
public:
virtual void displayArea()=0;
modifyShape (ShapeParams*) = 0;
};
class triangle :public shape
{
public:
void modifyShape (ShapeParams*) = override;
private:
TriangleParams m_params;
}
关于c++ - 用圆形和三角形设计形状类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44666561/