Behavior of c++ virtual calls inside constructor.
Last active
August 29, 2015 13:56
-
-
Save overminder/8894936 to your computer and use it in GitHub Desktop.
Behavior of c++ virtual calls inside constructor.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[@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