C++ 基于C+中专门化的重载+;

C++ 基于C+中专门化的重载+;,c++,inheritance,overloading,specialization,C++,Inheritance,Overloading,Specialization,我试图创建一个基于其参数专门化的重载函数,如: class DrawableObject...; class Mobile : public DrawableObject...; class Game { AddObject(DrawableObject * object) { // do something with object } AddObject(Mobile * object) { AddObject(dyna

我试图创建一个基于其参数专门化的重载函数,如:

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

class Game
{
    AddObject(DrawableObject * object)
    {
        // do something with object
    }
    AddObject(Mobile * object)
    {
        AddObject(dynamic_cast<DrawableObject *>(object));
        DoSomethingSpecificForSpecializedClass();
    }
};
类DrawableObject。。。;
移动类:公共DrawableObject。。。;
班级游戏
{
AddObject(DrawableObject*对象)
{
//用物体做某事
}
AddObject(移动*对象)
{
AddObject(动态_cast(object));
DoSomethingSpecificForSpecializedClass();
}
};
…但我的MS编译器给了我以下错误:

错误C2681:“Mobile*”:动态\u转换的表达式类型无效


这两个类都有虚拟函数。在这种情况下,这是向上投射的错误投射吗?我尝试过C风格的演员阵容,一切都按预期进行。此外,这种设计是否存在任何潜在的坑陷?

对于明确的向上浇铸,请使用
静态\u浇铸


你的设计应该很好用。请注意,如果试图传递一个可以隐式转换为
Mobile*
DrawableObject*
的对象,例如指向从
Mobile

派生的类的指针,则调用
AddObject()
将是不明确的,请使用
static\u cast


你的设计应该很好用。请注意,如果您试图传递一个可以隐式转换为
Mobile*
DrawableObject*
的对象,例如指向从
Mobile
派生的类的指针,则对
AddObject()
的调用将是不明确的,完全不需要-Mobile已经是一个DrawableObject。

演员阵容错误,完全不需要-Mobile已经是一个DrawableObject。

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

添加了编辑代码,我想澄清一些关于您设计的建议

要么您的“游戏”类统一处理所有对象,要么它不统一。如果没有,那么就没有必要提供一个公共可用的通用“AddObject”重载—您已经与各个对象紧密耦合,因此您最好放弃它和松散耦合设计的伪装。。您仍然可以将其作为私有助手函数AddObjectInternal使用。因为它不是重载,所以不需要强制转换来消除调用的歧义


如果您希望或希望统一对待所有对象,请考虑将当前放置在AdObject重载中的此类逻辑转换为对象类上的虚拟函数。然后,您只有一个AddObject方法,该方法调用添加的对象上的虚拟函数。

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

添加了编辑代码,我想澄清一些关于您设计的建议

要么您的“游戏”类统一处理所有对象,要么它不统一。如果没有,那么就没有必要提供一个公共可用的通用“AddObject”重载—您已经与各个对象紧密耦合,因此您最好放弃它和松散耦合设计的伪装。。您仍然可以将其作为私有助手函数AddObjectInternal使用。因为它不是重载,所以不需要强制转换来消除调用的歧义


如果您希望或希望统一对待所有对象,请考虑将当前放置在AdObject重载中的此类逻辑转换为对象类上的虚拟函数。然后,您只有一个AddObject方法,该方法调用所添加对象上的虚拟函数。

向上转换始终是免费和安全的。这意味着您不需要使用受保护的动态强制转换。静态类型转换是实现这一点的正确方法,尽管c样式转换也可以。实际上,您应该能够取消第二个AddObject函数,因为如果将指向移动对象的指针传递到DrawableObject函数中,它将调用适当的函数,而无需任何强制转换。除非你打算在重载函数中加入专门的功能,否则我不会写它。

上传总是免费和安全的。这意味着您不需要使用受保护的动态强制转换。静态类型转换是实现这一点的正确方法,尽管c样式转换也可以。实际上,您应该能够取消第二个AddObject函数,因为如果将指向移动对象的指针传递到DrawableObject函数中,它将调用适当的函数,而无需任何强制转换。除非你打算在重载函数中加入专门的功能,否则我不会写它。

As,cast是完全错误的
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
创建单独的方法。如果可以的话,我宁愿完全避开演员阵容。

因为演员阵容根本就错了
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
创建单独的方法。如果可以的话,我更愿意避免选角。

手机类:public drawable obbj中有一个拼写错误