1

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

基础:CDeviceClientRequest 子类:CDeviceSetEnabledRequest(基础) 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,就像我预期的那样。

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

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

4

1 回答 1

4

问题在于对象切片:当您按值返回时,您会返回该类型的实例,即使它是从派生类型实例化的:

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
  }

}

于 2013-08-05T12:15:18.627 回答