继承类的强制转换顺序?

时间:2010-10-20 12:19:43

标签: c++ oop

我有3节课:

class Super
{
    virtual int getType() { return 1; }
}
class Special : public class Super
{
    virtual int getType() { return 2; }
}
class SpecialSpecial : public class Special
{
    virtual int getType() { return 3; }
}

我有一个以std::vector<Super*>为参数的函数:

void handleClasses( std::vector<Super*> superVector )
{
    foreach element in superVector //Pseudocode!!
    {
        if( element->getType() == 1 )
            std::cout << "Thats a SuperClass" << std::endl;
        else if( element->getType() == 2 )
            std::cout << "Thats a SpecialClass" << std::endl;
        else if( element->getType() == 3 )
            std::cout << "Thats a SpecialSpecialClass" << std::endl;
    }
}

可能有一个继承自班级Special的用户:

class ParalellSpecial : public class Special
{
    virtual int getType() { return 4; }
}

现在函数handleClasses无法理解类型为4的新类,但它应该能够使用下一个高级类(在这种情况下它是Special)。

有人会如何实施这样的事情?是否存在允许创建类的层次顺序的设计模式,如果当前类无法使用(因为它未知),则下一个可用的超类将用作后备?

注意:类型标识符仅用于演示目的。肯定有更好的方法来识别C ++(RTTI)中的classtype。

3 个答案:

答案 0 :(得分:2)

这里有2个可能的答案:

1)如果你认为你需要知道一个对象到底是什么类型,那么也许你的封装是错误的。也许handleClasses()应该在对象上调用一个方法,每个类应该提供不同的实现吗?

2)如果这是您真正需要知道对象类型的极少数情况之一,请使用dynamic_cast<>。这就是它的用途。 E.g:

void handleClasses( std::vector<Super*> superVector )
{
    foreach element in superVector //Pseudocode!!
    {
        if( dynamic_cast<SpecialSpecial *>(element) != 0 )
            // SpecialSpecial or a subclass of SpecialSpecial 
            std::cout << "Thats a SpecialSpecialClass" << std::endl;
        else if( dynamic_cast<Special *>(element) != 0 )
            // Special or a subclass of Special
            std::cout << "Thats a SpecialClass" << std::endl;
        else
            // Super or a subclass of Super
            std::cout << "Thats a SuperClass" << std::endl;
    }
}

答案 1 :(得分:0)

这实际上取决于你的实际问题。通常,如果您的每个类都有特殊情况,而您无法使用多态,那么继承可能不是解决您问题的好方法。

另一个想法是创建一个知道类型关系的全局类型注册表。然后,您可以使用注册表在层次结构中移动,直到找到可以处理的类型。注册表可以只是一个DAG,其中type-id为节点。

答案 2 :(得分:0)

让事情发生变化的第一个解决方案:

子类将超类的类型集成到它们自己的Type-ID中 - Super获得Type == 1
- Special获得Type == 21
- SpecialSpecial获得Type == 321
- ParalellSpecial获取Type == 421

handleClasses现在检查第一个数字是否已知(ParalellSpecial不是这种情况。然后检查第二个数字是否已知(情况是这样)然后打印相关数字消息(或做任何想做的事情,例如从Super转换为Special

这个概念的缺点是每个层次结构级别只能有10个类。我认为,类型标识符的概念也不是最优的。

认为有更好的解决方案。