【发布时间】:2010-11-04 00:53:51
【问题描述】:
假设我有一个模板:
template <class N, class I>
void add(N* element, std::list<N*> & container, I (N::*f)() const,
std::string successmsg, std::string exceptmsg) {
//...
}
我想调用它以获得指向派生类的基类指针列表。
add(newAirplane, airplanes, &Airplane::getRegistration,
"Added!", "Error: Existent!");
Airplane 继承自 AirplaneType。
当然不会编译,N先定义为AirplaneType再定义为Airplane。
我添加了一个虚拟的getRegistration@AirplaneType 但是编译器当然会给出一个 vtable 错误。
解决这个问题的正确方法是什么? AirplaneType 没有 registration 属性,我对它不感兴趣。我也想避免virtual getRegistration() const {return "";}
有什么好的做法建议吗?
编辑:
感谢您的回答,但仍然无法正常工作。我想我找到了剩下的问题,但没有找到解决方案:
void Airline::addAirplane(AirplaneType* airplane) {
add(newAirplane, airplanes, &Airplane::getRegistration,
"Added!", "Error: Existent!");
}
收到的指针类型是AirplaneType,而不是Airplane。
airplanes 是AirplaneType 指针的列表。
【问题讨论】:
-
如果指针只有
AirplaneType*,那么你在做什么尝试调用Airplane的函数呢?如果引用必须是Airplane的实例,则可以static_cast指针。如果不是,那么如果AirplaneType有任何虚函数,你可以dynamic_cast,但是如果引用不是Airplane的实例,你打算怎么做? -
@Francisco:剩下的问题与模板无关。如果
f不是element的成员函数,则不能在element上调用f。不要介意模板,C++ 不够灵活,无法做到这一点。如果你的函数AddAirplane被传递一个指向Helicopter的指针,其中Helicopter派生自AirplaneType,而不是Airplane,该怎么办?当add需要在Helicopter上调用Airplane::getRegistration时应该发生什么。如果这是不可能的,实际上AirplaneType*必须指向Airplane,那么理想情况下addAirplane应该采用Airplane*。 -
@Francisco:当然,如果您将
getRegistration设为AirplaneType的虚函数,那么您就可以了,因为您可以在任何AirplaneType*上调用它。那么你就不再需要模板中的额外类型了。 -
@Francisco:是的,可以做到。指向虚拟成员函数的指针按照您希望的方式工作 - 即使对象指针和成员函数指针都是基类类型,也会调用正确的覆盖。我已经编辑了我的答案来演示。
标签: c++ class inheritance virtual