如何在向方法传递超类时防止自动下转换

How to prevent automatic downcasting when passing a superclass to/from a method

本文关键字:转换 超类 方法      更新时间:2023-10-16

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

base:CDeviceClientRequest子类:CDeviceSetEnabledRequest(基本)inst类:CDeviceGPSSetEnabledRequest*(子类)inst类: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()方法来验证这一点类的名称,并且我只得到"I are a CDeviceClientRequest"。某个地方的事实它正在处理一个派生类。

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

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

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
  }

}