我想知道子类是否覆盖了虚方法,在这种情况下,我想将实例插入特殊列表中以进行其他处理。 到目前为止我使用CRTP:
template<class T>
class P {
public:
P() {
if (!std::is_same<decltype(&T::foo),decltype(&P::foo)>::value)
.........do something.........
}
virtual ~P(){}
virtual void foo() {}
}
class Child: public P<Child> {
public:
Child() {
}
virtual void foo() {
}
}
我想知道在这种情况下是否有一些技巧可以避免CRTP,因为目前P类不是模板,我应该更改几行代码。我可以,但我想知道是否有其他选择。我尝试使用相同的模式但只是在另一个函数中,而不是在P构造函数中,但是 我应该迭代P的任何一个孩子(我有几个子类)。是否可以“迭代类型”?我有一个P指针列表,但很明显 运行时检查与std :: is_same之类的静态检查有很大不同。一世 试图使用:
(void*)(obj.*(&P::foo)) != (void*)(&P::foo)
它实际上适用于gcc 4.8.1但是我应该使用-Wno-pmf-conversions禁用警告,它似乎不是最好的选择。
答案 0 :(得分:2)
我想知道子类是否覆盖了虚方法
在运行时没有官方方法来确定。您可能需要深入研究对象的RTTI(如果它提供了足够丰富的信息),甚至可以直接挖掘vtable,或者使用其他特定于编译器的技巧来比较方法。
在这种情况下,我想将实例插入特殊列表中以进行其他处理。
然后我建议采用不同的方法 - 改用接口。声明一个只包含您感兴趣的虚方法的抽象类,然后只有在他们打算实现该方法时才从该接口派生其他类。
这样,如果对象实现了接口,则可以使用dynamic_cast
在运行时测试对象。</ p>
尝试这样的事情:
class Foo
{
public:
virtual void foo() = 0;
};
class P
{
public:
virtual ~P() { }
};
class Child : public P, public Foo
{
public:
Child() { }
void foo() override { }
};
然后你可以这样做:
P *p = new Child;
...
Foo *f = dynamic_cast<Foo*>(p);
if (f) listOfFoos.push_back(f);
...
for (Foo *f : listOfFoos)
f->foo();
...