检查子类是否执行了方法重写



>我想知道子类是否覆盖了虚拟方法,在这种情况下,我想将实例插入到特殊列表中以进行其他处理。 到目前为止,我使用 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();
...

最新更新