基于C ++专业化的重载

时间:2010-01-07 21:43:23

标签: c++ inheritance overloading specialization

我正在尝试根据其参数的特化创建一个重载的函数,例如:

class DrawableObject...;
class Mobile : public DrawableObject...;

class Game
{
    AddObject(DrawableObject * object)
    {
        // do something with object
    }
    AddObject(Mobile * object)
    {
        AddObject(dynamic_cast<DrawableObject *>(object));
        DoSomethingSpecificForSpecializedClass();
    }
};

...但是我的MS编译器给了我这个错误:

  

错误C2681:'Mobile *':dynamic_cast

的表达式类型无效

这两个类都有虚函数。在这种情况下,这是否适合投射?我尝试过使用C风格的演员,一切都按预期运行。此外,这种设计是否有潜在的陷阱?

5 个答案:

答案 0 :(得分:4)

对于显式向上转发,请使用static_cast

你的设计应该可以正常工作。请注意,如果您尝试传递可以隐式转换为AddObject()Mobile*的对象,则对DrawableObject*的调用将不明确,例如指向从{{{{}}派生的类的指针1}}。

答案 1 :(得分:1)

作为Neil stated,施法者完全错了。 dynamic_cast<>用于向下转换从基础到衍生而不是相反。更好的方法是将公共代码分解为:

class Game {
protected:
    void commonAddObject(DrawableObject *obj) {
        // do common stuff here
    }
public:
    void addObject(DrawableObject *obj) {
        commonAddObject(obj);
        // do DrawableObject specific stuff here
    }
    void addObject(MobileObject *obj) {
        commonAddObject(obj);
        // do MobileObject specific stuff here
    }
};

或为DrawableObjectMobileObject创建不依赖于类型重载的单独方法。如果可以的话,我宁愿完全避开铸造。

答案 2 :(得分:0)

演员表是错误的,完全没必要 - Mobile已经是一个可绘制的对象。

答案 3 :(得分:0)

...或完全删除AddObject(Mobile *对象)重载。如果没有该函数,它将被“隐式地”转换为它的基类,并且将调用AddObject(DrawableObject *)函数。您无需为层次结构中的每种类型手动添加重载和转换。

修改代码已添加,我想澄清一些有关您设计的建议。

您的“游戏”类可以统一处理所有对象,也可以不处理。如果没有,那么提供一个公开可用的通用“AddObject”重载是没有意义的 - 你已经与各个对象紧密耦合,所以你不妨放弃它和松散耦合设计的特征。您仍然可以将它作为私有辅助函数AddObjectInternal。由于它不是重载,因此您不需要使用强制转换来消除呼叫的歧义。

如果您希望或者希望统一处理所有对象,请考虑将当前放入AddObject重载的逻辑放入对象类的虚函数中。然后,您只有一个AddObject方法,该方法调用添加的对象上的虚函数。

答案 4 :(得分:0)

向上转换始终是免费且安全的。这意味着您不需要使用受保护的dynamic_cast。 static_cast是执行此操作的正确方法,尽管c样式的强制转换也可以正常工作。实际上你应该能够取消第二个AddObject函数,因为如果你将一个指向Mobile对象的指针传递给DrawableObject函数,它将调用正确的函数而不需要任何转换。除非你打算在重载函数中放入专门的功能,否则我不会写它。