c – 面向对象:如何从多个实现中进行选择

前端之家收集整理的这篇文章主要介绍了c – 面向对象:如何从多个实现中进行选择前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我是一个不错的程序程序员,但我是面向对象的新手(我曾经在好老帕斯卡和C上接受过工程师培训).我发现特别棘手的是选择多种方法中的一种来实现同样的目的.对于C来说尤其如此,因为它的功能可以让你做任何你喜欢的事情,甚至可怕的事情(我想这里的权力/责任格言是合适的).

我认为这可能有助于我运行一个我正在与社区斗争的特定案例,以了解人们如何做出这些选择.我正在寻找的是与我的具体情况相关的建议,以及更一般的指针(没有双关语意).开始:

作为练习,我正在开发一个简单的模拟器,其中“几何表示”可以有两种类型:“圆”或“多边形”.然后,模拟器的其他部分将需要接受这些表示,并可能以不同方式处理它们.我已经提出了至少四种不同的方法来做到这一点.每个的优点/缺点/权衡取舍是什么?

答:功能重载

将Circle和Polygon声明为不相关的类,然后重载需要几何表示的每个外部方法.

B:铸造

声明一个枚举GeometricRepresentationType {Circle,Polygon}.声明一个抽象的GeometricRepresentation类,并从中继承Circle和Polygon. GeometricRepresentation有一个虚拟的Gettype()方法,由Circle和Polygon实现.然后,方法使用GetType()和switch语句将GeometricRepresentation转换为适当的类型.

C:不确定合适的名字

像在B中一样声明一个枚举类型和一个抽象类.在这个类中,还创建函数Circle * ToCircle(){return NULL;}和Polygon * ToPolygon(){return NULL;}.每个派生类然后重载相应的函数,返回此.这仅仅是动态铸造的重新发明吗?

D:一起束缚他们

将它们实现为具有枚举成员的单个类,该成员指示对象的类型.该类具有可以存储两种表示的成员.然后由外部方法决定不调用函数(例如,多边形上的GetRadius()或圆上的GetOrder()).

解决方法

以下是我教我的OO学生的一些设计规则(拇指):

1)每当你想要创建一个枚举以跟踪对象/类中的某些模式时,你可以(可能更好)为每个枚举值创建一个派生类.

2)任何时候你写一个关于一个对象的if语句(或者它当前的状态/模式/无论什么),你可以(可能更好)进行一个虚函数调用来执行一些(更抽象的)操作,其中原始的那个 – 或者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;
}

做这个:

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

在上面的例子中,非常明显的是“更抽象”的想法是什么,外围.情况并非总是如此.有时它甚至没有一个好名字,这是很难“看到”的原因之一.但是,您可以将任何if语句转换为虚函数调用,其中“if”部分被函数的虚拟替换.

在你的情况下,我绝对同意Avi的答案,你需要一个基类/接口类和派生圆和多边形的子类.

猜你在找的C&C++相关文章