我正在尝试根据其参数的特化创建一个重载的函数,例如:
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风格的演员,一切都按预期运行。此外,这种设计是否有潜在的陷阱?
答案 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
}
};
或为DrawableObject
和MobileObject
创建不依赖于类型重载的单独方法。如果可以的话,我宁愿完全避开铸造。
答案 2 :(得分:0)
演员表是错误的,完全没必要 - Mobile已经是一个可绘制的对象。
答案 3 :(得分:0)
...或完全删除AddObject(Mobile *对象)重载。如果没有该函数,它将被“隐式地”转换为它的基类,并且将调用AddObject(DrawableObject *)函数。您无需为层次结构中的每种类型手动添加重载和转换。
修改代码已添加,我想澄清一些有关您设计的建议。
您的“游戏”类可以统一处理所有对象,也可以不处理。如果没有,那么提供一个公开可用的通用“AddObject”重载是没有意义的 - 你已经与各个对象紧密耦合,所以你不妨放弃它和松散耦合设计的特征。您仍然可以将它作为私有辅助函数AddObjectInternal。由于它不是重载,因此您不需要使用强制转换来消除呼叫的歧义。
如果您希望或者希望统一处理所有对象,请考虑将当前放入AddObject重载的逻辑放入对象类的虚函数中。然后,您只有一个AddObject方法,该方法调用添加的对象上的虚函数。
答案 4 :(得分:0)
向上转换始终是免费且安全的。这意味着您不需要使用受保护的dynamic_cast。 static_cast是执行此操作的正确方法,尽管c样式的强制转换也可以正常工作。实际上你应该能够取消第二个AddObject函数,因为如果你将一个指向Mobile对象的指针传递给DrawableObject函数,它将调用正确的函数而不需要任何转换。除非你打算在重载函数中放入专门的功能,否则我不会写它。