>我想知道子类是否覆盖了虚拟方法,在这种情况下,我想将实例插入到特殊列表中以进行其他处理。 到目前为止,我使用 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-转换禁用警告,这似乎不是最佳选择。
我想知道子类是否覆盖了虚拟方法
没有官方方法可以在运行时确定这一点。您可能必须深入研究对象的 RTTI(如果它提供了足够丰富的信息(甚至直接使用 vtable,或者使用其他特定于编译器的技巧来比较方法。
在这种情况下,我想将实例插入到特殊列表中以进行其他处理。
然后我建议一种不同的方法 - 改用接口。声明一个仅包含您感兴趣的虚拟方法的抽象类,然后仅当其他类打算实现该方法时才从该接口派生。
这样,您可以使用dynamic_cast
在运行时测试对象是否实现接口。
尝试这样的事情:
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();
...