我有几个派生自顶级超类的类:
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”。某处事实 它正在处理派生类已经丢失了。
任何帮助非常感谢。 (注意:我已大大简化了帖子的代码)。
答案 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
}
}