当て推量を使わずに、実行時に伝える方法を考えました。ポリモーフィッククラスのvptrを0でオーバーライドするだけで、メソッドが呼び出されるかどうか、またはセグメンテーション違反が発生するかどうかを確認できます。これは私の例で得られるものです:
Concrete: Base
Concrete: Derived
Pointer: Base
Pointer: Derived
DELETING VPTR!
Concrete: Base
Concrete: Derived
Segmentation fault
whereは、具象型を介したConcrete: T
仮想メンバー関数の呼び出しが成功したことを意味します。T
同様に、ポインタを介してPointer: T
のメンバー関数の呼び出しが成功したと言います。T
Base
参考までに、これは私のテストプログラムです。
#include <iostream>
#include <string.h>
struct Base {
unsigned x;
Base() : x(0xEFBEADDEu) {
}
virtual void foo() const {
std::cout << "Base" << std::endl;
}
};
struct Derived : Base {
unsigned y;
Derived() : Base(), y(0xEFCDAB89u) {
}
void foo() const {
std::cout << "Derived" << std::endl;
}
};
template <typename T>
void dump(T* p) {
for (unsigned i = 0; i < sizeof(T); i++) {
std::cout << std::hex << (unsigned)(reinterpret_cast<unsigned char*>(p)[i]);
}
std::cout << std::endl;
}
void callfoo(Base* b) {
b->foo();
}
int main() {
Base b;
Derived d;
dump(&b);
dump(&d);
std::cout << "Concrete: ";
b.foo();
std::cout << "Concrete: ";
d.foo();
std::cout << "Pointer: ";
callfoo(&b);
std::cout << "Pointer: ";
callfoo(&d);
std::cout << "DELETING VPTR!" << std::endl;
memset(&b,0,6);
memset(&d,0,6);
std::cout << "Concrete: ";
b.foo();
std::cout << "Concrete: ";
d.foo();
std::cout << "Pointer: ";
callfoo(&b);
std::cout << "Pointer: ";
callfoo(&d);
return 0;
}