【发布时间】:2016-06-23 07:37:22
【问题描述】:
在我开始编写的这段代码中,我遇到了一个不适合我的常见模式。通常,它涉及枚举、映射、开关和某种类层次结构。我试图抽象出一个 MWE:
#include <iostream>
#include <map>
class Shape {
public:
virtual double SumOfInternalAngles() { throw std::exception(); }
};
class Triangle : public Shape {
public:
double SumOfInternalAngles() { return 180.0; }
};
class Rectangle : public Shape {
public:
double SumOfInternalAngles() { return 360.0; }
};
enum TeamShapes {AlicesTriangle, BobsRectangle, CarolsTriangle};
int main()
{
Triangle alicesTriangle;
Rectangle bobsRectangle;
Triangle carolsTriangle;
std::map<TeamShapes, Shape*> shapeMap;
shapeMap[TeamShapes::AlicesTriangle] = &alicesTriangle;
shapeMap[TeamShapes::BobsRectangle] = &bobsRectangle;
shapeMap[TeamShapes::CarolsTriangle] = &carolsTriangle;
for(auto it : shapeMap)
{
switch (it.first)
{
case TeamShapes::AlicesTriangle:
std::cout << it.second->SumOfInternalAngles() << std::endl;
break;
case TeamShapes::BobsRectangle:
std::cout << static_cast<Rectangle*>(it.second)->SumOfInternalAngles() << std::endl;
break;
}
}
return 0;
}
似乎有重复的信息,访问成员函数的两个版本都有缺点:第一种情况,你需要在基类中有一个虚成员函数,这意味着所有的派生类都变得“杂乱无章”具有对他们没有真正意义的功能,例如Circle 会以函数 getCorners() 结束。在第二种情况下,我宁愿不需要演员表,尽管我知道这是必要的。也许有人可以指出我可以为这种情况提出更好设计的方向。
我对 C++ 很陌生,所以我想听听关于此类构造的“最佳实践”和“约定”是什么。也许代码没问题,我只需要调整?
【问题讨论】:
-
for(auto it复制映射中的键值对。在这里无关紧要,但通常你会想要for(auto &it。 -
为什么你认为在你的例子中演员是必要的?不是。
-
我知道这没有必要(我使用了没有3行以上的版本),但我不希望在基类中有
SumOfInternalAngles,然后它会是必要的。 -
不要将相关的类型放在同一个容器中,然后区别对待(通过尝试访问派生类方法)。如果您需要以不同的方式对待您的对象,请考虑将它们保存在separate containers。
-
是的,这可能正是困扰我的地方。
Shape的map要使用多态,然后枚举和switch做相反的事情。
标签: c++ enums polymorphism containers