How can a C++ base class determine at runtime if a method has been overridden?

后端 未结 3 1296
感动是毒
感动是毒 2021-01-13 11:55

The sample method below is intended to detect whether or not it has been overridden in a derived class. The error I get from MSVC implies that it is simply wrong to try to g

3条回答
  •  北恋
    北恋 (楼主)
    2021-01-13 12:25

    You can actually find this out. We encountered the same problem and we found a hack to do this.

    #include
    #include
    #include
    
    using namespace std;
    
    class A {
    public:
        virtual void hi(int i) {}
        virtual void an(int i) {}
    };
    
    class B : public A {
    public:
        void hi(int i) {
            cout << i << " Hello World!" << endl;
        }
    };
    

    We have two classes A and B and B uses A as base class.

    The following functions can be used to test if the B has overridden something in A

    int function_address(void *obj, int n) {
        int *vptr = *(int **)&obj;
        uintptr_t vtbl = (uintptr_t)*vptr;
    
        // It should be 8 for 64-bit, 4 for 32-bit 
        for (int i=0; i(p);
    }
    
    bool overridden(void *base, void* super, int n) {
        return (function_address(super, n) != function_address(base, n));
    }
    

    The int n is the number given to method as they are stored in vtable. Generally, it's the order you define the methods.

    int main() {
        A *a = new A();
        A *b = new B();
    
        for (int i=0; i<2; i++) {
            if (overridden(a, b, i)) {
                cout << "Function " << i << " is overridden" << endl;
            }
        }
    
        return 0;
    }
    

    The output will be

    Function 0 is overridden

    EDIT: We get the pointers to vtables for each class instance and then compare the pointer to the methods. Whenever a function is overridden, there will be a different value for super object.

提交回复
热议问题