Вы действительно можете это выяснить. Мы столкнулись с той же проблемой, и мы нашли способ сделать это.
#include<iostream>
#include<cstdio>
#include<stdint.h>
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;
}
};
У нас есть два класса A
и B
, а B
использует A
в качестве базового класса.
Следующие функции могут использоваться для проверки того, что B
что-то переопределило в 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<n; i++) vtbl+=8;
uintptr_t p = (uintptr_t) vtbl;
return *reinterpret_cast<int*>(p);
}
bool overridden(void *base, void* super, int n) {
return (function_address(super, n) != function_address(base, n));
}
int n
- это номер, данный методу, поскольку они хранятся в vtable. Обычно это порядок, в котором вы определяете методы.
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;
}
Вывод будет
Function 0 is overridden
EDIT: Мы получаем указатели на vtables для каждого экземпляра класса, а затем сравниваем указатель на методы. Всякий раз, когда функция переопределяется, для суперобъекта будет другое значение.