如何在将超类传入/传出方法时阻止自动向下转换

时间:2013-08-05 12:10:28

标签: c++

我有几个派生自顶级超类的类:

base:CDeviceClientRequest 子类:CDeviceSetEnabledRequest(base) inst-class:CDeviceGPSSetEnabledRequest *(子类) inst-class:CDeviceTotalStationSetEnabledRequest *(子类)

只有标有*的那些是可实例化的,其他的都有受保护的构造函数,即 构造函数调用基类构造函数,设置私有成员变量。

我正在通过一种方法构建它们:

CDeviceClientRequest getRequest(int type)
{
    switch (type)
    {
    GPS_SET_ENABLED: return CDeviceGPSSetEnabledRequest();
    TS_SET_ENABLED : return CDeviceTotalStationSetEnabledRequest();
    default:
       // raise an unknown type exception
    }
}

然后我有一些调用请求的代码:

void invoke(CDeviceClientRequest& request)
{
    // some code
}

所以我的代码看起来像这样:

CDeviceClientRequest request = getRequest(GPS_SET_ENABLED);
invoke(request);

我的问题是虽然我正在调用CDeviceGPSSetEnabledRequest()的构造函数, 从getRequest()返回的是一个CDeviceClientRequest,以及传递给调用的内容 也是一个CDeviceClientRequest,而不是像我预期的CDeviceGPSSetEnabledRequest。

我通过向std :: cout的所有超类和基类添加一个简单的whatAmI()方法来验证这一点 类的名称,我只得到“我是一个CDeviceClientRequest”。某处事实 它正在处理派生类已经丢失了。

任何帮助非常感谢。 (注意:我已大大简化了帖子的代码)。

1 个答案:

答案 0 :(得分:4)

问题是object slicing:当你按值返回时,你返回该类型的实例,即使它是从派生类型实例化的:

CDeviceClientRequest getRequest(int type);

这只能返回CDeviceClientRequest类型的对象。您可以通过返回基本类型的智能指针来解决此问题。

std::unique_ptr<CDeviceClientRequest> getRequest(int type)
{
  switch (type)
  {
    GPS_SET_ENABLED: 
      return std::unique_ptr<CDeviceClientRequest>(new CDeviceGPSSetEnabledRequest);
    TS_SET_ENABLED : 
      return std::unique_ptr<CDeviceClientRequest>(new CDeviceTotalStationSetEnabledRequest);
    default:
   // raise an unknown type exception
  }

}