Skip to content

Instantly share code, notes, and snippets.

@overminder
Last active August 29, 2015 13:56
Show Gist options
  • Save overminder/8894936 to your computer and use it in GitHub Desktop.
Save overminder/8894936 to your computer and use it in GitHub Desktop.
Behavior of c++ virtual calls inside constructor.

Description

Behavior of c++ virtual calls inside constructor.

#include <cstdio>
#include <cstddef>
#include <cstdint>
class Base {
public:
Base() { }
Base(void *) {
// Get vtable
if (!baseVTab) {
baseVTab = *((intptr_t *) this);
}
}
// LOL
Base(int);
virtual const char *getName() {
return "Base";
}
static intptr_t baseVTab;
};
class Sub : public Base {
public:
Sub(void *) : Base((void *) 0) {
// Get vtable
if (!subVTab) {
subVTab = *((intptr_t *) this);
}
}
// Another LOL
Sub(int);
virtual const char *getName() {
return "Sub";
}
static intptr_t subVTab;
};
Base::Base(int) {
*((intptr_t *) this) = Sub::subVTab;
printf("[@%p] Base ctor, this->getName() = %s\n", this, getName());
printf("[@%p] Base ctor, ((Sub *) this)->getName() = %s\n",
this, ((Sub *) this)->getName());
}
Sub::Sub(int) {
*((intptr_t *) this) = Sub::baseVTab;
printf("[@%p] Sub ctor, this->getName() = %s\n", this, getName());
printf("[@%p] Sub ctor, ((Base *) this)->getName() = %s\n",
this, ((Base *) this)->getName());
}
intptr_t Base::baseVTab = 0;
intptr_t Sub::subVTab = 0;
int main() {
{
// Get vtables
Sub s((void *) 0);
}
Base b((int) 0);
Sub s((int) 0);
return 0;
}
[@000000000022FE50] Base ctor, this->getName() = Base
[@000000000022FE50] Base ctor, ((Sub *) this)->getName() = Sub
[@000000000022FE40] Sub ctor, this->getName() = Sub
[@000000000022FE40] Sub ctor, ((Base *) this)->getName() = Base
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment