You can verify this by viewing the contents of the object. I wrote this simple program that prints the contents of a base class, a derived class, and a class that matches the base class, but with the usual method instead of the virtual one:
#include <iostream> #include <string> #include <iomanip> using namespace std; class Base { public: virtual void show() {} }; class Derived : public Base { }; class NonVirtual { public: void show() {} }; struct Test { int data1, data2; }; template <typename T> void showContents(T* obj, string name) { Test* test = new Test{}; test = reinterpret_cast<Test*>(obj); cout << name << ": " << hex << "0x" << test->data1 << " " << "0x" << test->data2 << endl; delete test; } int main() { Base* base = new Base{}; Derived* derived = new Derived{}; NonVirtual* nonVirtual = new NonVirtual{}; showContents(base, "Base"); showContents(derived, "Derived"); showContents(nonVirtual, "NonVirtual"); delete base; delete derived; delete nonVirtual; }
Live demo
The result of executing the above program after compiling with cpp.sh (I'm not sure which compiler is used there):
Base: 0x4013e0 0x0 Derived: 0x401400 0x0 NonVirtual: 0x0 0x0
so I expect this to mean that a virtual table was actually created for the Derived object (at least for this compiler), since the required behavior is not defined in the C ++ standard).
source share