oop设计用于多态处理对象

时间:2011-11-15 06:44:10

标签: c++ oop design-patterns polymorphism

我有从一个基础派生的不同类型的对象(例如圆形,矩形,多边形等等),我有一组可以应用于这些对象的预定义操作(例如移动,旋转,复制...等等)。 在这种情况下我喜欢的解决方案是访问者模式。我有每个操作的访问者,其中包含所有类型的全套操作。这允许我在不改变对象本身的情况下向对象添加新函数。操作肯定会被更改,并且比新对象类型更频繁地添加,所以这真的很棒,但是有一个问题。 上述所有内容都是作为一个库实现的,该库可能(并将在未来)由另一个程序员扩展。程序员可以添加新类型的对象,或者是否实现操作。例如,可以添加支持移动的“三角形”类,但不支持旋转。在这种情况下,程序员将无法扩展我的访问者来处理他的对象的移动操作。 我看到了另外一个解决方案 - 拥有i_movable,i_rotatable,i_copyable等接口。每个类实现一个或多个这样的接口,然后我检查我的库,如果指定的对象支持给定的dynamic_cast接口并应用操作。像

这样的东西
if (i_movable* m = dynamic_cast<i_movable>(obj)) m->move(10, 20);

但我不太喜欢这个解决方案。任何人都可以提出更好的建议吗?

这对于OOP设计可能并不重要,但实现的语言是C ++,所以我受限于C ++功能。

更新

如果没有人能想出更好的解决方案,请至少对提议的人投票吗?

提前致谢。

2 个答案:

答案 0 :(得分:0)

而不是:

if (i_movable* m = dynamic_cast<i_movable>(obj)) m->move(10, 20);

你可以使用一些模板元编程技巧(看看boost::is_base_of):

#include "boost/type_traits/is_base_of.hpp" 
#include <iostream>

struct i_move
{
    virtual void move(const float, const float ) = 0;
};
struct Triangle
{
    // not movable
};
struct Circle : i_move
{
    virtual void move(const float, const float )
    {
        // move me
    }
};

template< class D >
bool IsMovable( D&)
{
    return boost::is_base_of<i_move,D>::value;
}

int main()
{
    Circle a;
    Triangle b;
    std::cout<<std::boolalpha<<IsMovable(a)<<std::endl;
    std::cout<<std::boolalpha<<IsMovable(b)<<std::endl;
}

答案 1 :(得分:0)

如果我理解正确,如果不支持该操作,则不执行任何操作(或者更常见的是,具有与所讨论的对象无关的统一行为)。然后一个简单的解决方案是在基类中提供默认行为,然后如果派生类没有实现自己的版本,则默认行为会在没有任何额外机制的情况下自动启动。

如果我没记错的话,在Borland的Turbo Vision中这样的方法被称为“伪抽象”:它们并不是真正抽象的(它不被禁止调用它们,并且没有严格的需要在派生类中覆盖它们),但它们除非被覆盖,否则什么都不做。