MGA*_*MGA 7 c++ oop polymorphism casting
我是一个不错的程序程序员,但我是一个面向对象的新手(我是一个好老帕斯卡和C的工程师.)我觉得特别棘手的是选择其中一种方法来实现同样的目的.对于C++来说尤其如此,因为它的强大功能可以让你做任何你喜欢的事情,甚至可怕的事情(我想这里的权力/责任格言是合适的).
我认为这可能有助于我运行一个我正在与社区斗争的特定案例,以了解人们如何做出这些选择.我正在寻找的是与我的具体案例相关的建议,以及更一般的指针(没有双关语意).开始:
作为练习,我正在开发一个简单的模拟器,其中"几何表示"可以有两种类型:"圆"或"多边形".然后,模拟器的其他部分需要接受这些表示,并可能以不同方式处理它们.我已经提出了至少四种不同的方法来做到这一点.每个的优点/缺点/权衡取舍是什么?
答:功能重载
声明Circle
和Polygon
作为不相关的类,然后重载需要几何表示的每个外部方法.
B:铸造
宣布一个enum GeometricRepresentationType {Circle, Polygon}
.声明一个抽象GeometricRepresentation
类和继承Circle
,并Polygon
从它.GeometricRepresentation
有一个GetType()
由Circle
和实现的虚方法Polygon
.然后使用方法GetType()
和switch语句将a GeometricRepresentation
转换为适当的类型.
C:不确定合适的名字
声明枚举类型和抽象类,如B中所示.在这个类中,还创建函数Circle* ToCircle() {return NULL;}
和Polygon* ToPolygon() {return NULL;}
.然后每个派生类重载相应的函数,返回this
.这仅仅是动态铸造的重新发明吗?
D:一起束缚他们
将它们实现为具有枚举成员的单个类,该成员指示对象的类型.该类具有可以存储两种表示的成员.然后由外部方法决定不要调用愚蠢的函数(例如GetRadius()
在多边形或GetOrder()
圆上).
以下是我教给面向对象学生的一些设计规则(经验):
1)任何时候你想创建一个枚举来跟踪对象/类中的某些模式,你可以(可能更好)为每个枚举值创建一个派生类。
2)任何时候你编写一个关于对象(或其当前状态/模式/其他)的 if 语句,你都可以(可能更好)进行虚拟函数调用来执行一些(更抽象的)操作,其中原始的 then- 或else-sub-statement 是派生对象的虚函数的主体。
例如,不要这样做:
if (obj->type() == CIRCLE) {
// do something circle-ish
double circum = M_PI * 2 * obj->getRadius();
cout << circum;
}
else if (obj->type() == POLY) {
// do something polygon-ish
double perim = 0;
for (int i=0; i<obj->segments(); i++)
perm += obj->getSegLength(i);
cout << perim;
}
Run Code Online (Sandbox Code Playgroud)
做这个:
cout << obj->getPerimeter();
...
double Circle::getPerimeter() {
return M_PI * 2 * obj->getRadius();
}
double Poly::getPerimeter() {
double perim = 0;
for (int i=0; i<segments(); i++)
perm += getSegLength(i);
return perim;
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,“更抽象”的概念是什么是非常明显的,周长。情况并非总是如此。有时它甚至连一个好名字都没有,这也是它很难“看见”的原因之一。但是,您可以将任何 if 语句转换为虚拟函数调用,其中“if”部分被函数的虚拟性替换。
就你的情况而言,我绝对同意 Avi 的答案,你需要一个基/接口类以及 Circle 和 Polygon 的派生子类。
归档时间: |
|
查看次数: |
241 次 |
最近记录: |