检查子类是否执行了方法覆盖

时间:2018-05-05 16:32:48

标签: c++ c++11

我想知道子类是否覆盖了虚方法,在这种情况下,我想将实例插入特殊列表中以进行其他处理。 到目前为止我使用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禁用警告,它似乎不是最好的选择。

1 个答案:

答案 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();
...