【问题标题】:runtime-check whether an instance (Base*) override a parent function (Base::f())运行时检查实例 (Base*) 是否覆盖父函数 (Base::f())
【发布时间】:2017-12-24 03:19:04
【问题描述】:

如何判断基类(B)的指针是否(多态性)覆盖了基类的某个虚函数?

class B{
    public: int aField=0;
    virtual void f(){};
};
class C : public B{
    public: virtual void f(){aField=5;};
};
class D: public B{};

int main() {
    B b;
    C c;
    D d;
    std::vector<B*> bs;
    bs.push_back(&b);
    bs.push_back(&c);
    bs.push_back(&d);
    for(int n=0;n<3;n++){
        //std::cout<<(bs[n]->f)==B::f<<std::endl;
        //should print "true false true"
    }
}

我尝试比较函数指针bs[n]-&gt;fB::f 的地址,但无法编译。

Demo

感觉这个问题可能是重复的,但是找不到(抱歉)。

【问题讨论】:

  • 你想在这里做什么?这似乎是X Y problem
  • @Justin 主要是出于好奇。我想知道这是否可能......它可能对一些罕见的优化案例有用(如果我碰巧需要它)。
  • 这个问题没有多大意义;因为f 是虚拟的,所以bs[n]-&gt;f 始终是虚拟调用
  • 你的意思是问:如何判断*bs[n]是否有动态类型B
  • @M.M 不,我只想检查单个特定函数 f 是否被覆盖。例如checkF(static_cast&lt;B*&gt;(new D())) 应该返回“它没有被覆盖”。 .... D 可以覆盖B 的其他虚函数,但我不在乎。

标签: c++ c++14 virtual-functions


【解决方案1】:

GCC has an extension 允许您获取虚拟成员函数的地址。

可以这样使用:

#include <vector>
#include <iostream>

class B{
    public: int aField=0;
    virtual void f(){};
};
class C : public B{
    public: virtual void f(){aField=5;};
};
class D: public B{};

int main() {
    B b;
    C c;
    D d;
    std::vector<B*> bs;
    bs.push_back(&b);
    bs.push_back(&c);
    bs.push_back(&d);
    for(int n=0;n<3;n++){
        // This might need to be: (void*) B{}.*&B::f == (void*) (...)
        std::cout << ((void*) &B::f == (void*)(bs[n]->*&B::f)) << '\n';
    }
}

Demo

您可能会觉得this QA 很有趣。

当然,这是非标准行为。如果您想在标准 C++ 中实现类似的行为,您实际上可能正在寻找 纯虚 函数:

class B{
    public: int aField=0;
    virtual void f() = 0;
};

否则,您必须使用其他机制进行通信,例如 f() 上的 bool 返回类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    相关资源
    最近更新 更多