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

C++ 检查子类是否执行了方法重写,c++,c++11,C++,C++11,我想知道一个子类是否重写了一个虚方法,在这种情况下,我想在一个特殊的列表中插入该实例以进行额外的处理。 到目前为止,我使用CRTP所拥有的: template<class T> class P { public: P() { if (!std::is_same<decltype(&T::foo),decltype(&P::foo)>::value) .........do something.........

我想知道一个子类是否重写了一个虚方法,在这种情况下,我想在一个特殊的列表中插入该实例以进行额外的处理。 到目前为止,我使用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() {
    }
}
它实际上与GCC4.8.1一起工作,但我应该使用-Wno pmf转换禁用警告,而且它似乎不是最佳选择

我想知道子类是否重写了虚方法

在运行时没有正式的方法来确定这一点。您可能需要深入研究对象的RTTI(如果它提供了足够丰富的信息),甚至直接研究vtable,或者使用其他特定于编译器的技巧来比较方法

在本例中,我希望将实例插入一个特殊列表中以进行额外处理

然后,我建议使用另一种方法——使用接口。声明一个只包含您感兴趣的虚拟方法的抽象类,然后让您的其他类仅在打算实现该方法时从该接口派生

通过这种方式,您可以使用
dynamic\u 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();
...
然后你可以这样做:

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();
...
P*P=新子女;
...
Foo*f=动态投影(p);
如果(f)列出食物,则向后推(f);
... 
对于(Foo*f:listofoos)
f->foo();
...

P
中为每个成员函数设置一个私有
bool
变量对您有用吗?它可以工作,实际上这是我的第一个想法,但我正在尝试“自动”操作,我的意思是,如果开发人员没有设置bool变量,它将不再工作,这可能是一个小错误。您可以使用
final
来阻止其他类从您的类派生,但否则您通常无法知道谁从您的类派生,或者影响他们做什么(或不做什么)。当然,但这些类是同一个可执行文件的一部分,只是不同的开发人员。我敢说,比较C++中的成员函数地址与依赖于实现定义的行为是一致的,因为C++标准没有定义动态绑定应该如何工作的实现策略,只是另一个好的选择。现在接受的答案。