I'm trying to understand how casting between base & derived types exactly works in C++. So I wrote a small proof-of-concept program
class Foo {
public:
Foo() {}
};
// Bar is a subclass of Foo
class Bar : public Foo {
public:
Bar() : Foo() {}
void bar() { std::cout << "bar" << std::endl; }
void bar2() { std::cout << "bar with " << i << std::endl; }
private:
int i = 0;
};
where Foo is the base and Bar is derived from Foo.
Currently, my understandings of casting are:
- Cast is a runtime thing. Compiler can do us a favor by checking them during compilation, but the actual type conversion occurs during runtime
- Upcast (e.g.
Foo f = Bar()
), either explicit or implicit, should be always fine - Downcast (e.g.
Bar b = Foo()
) is prohibited in C++, although we can enforce the cast by usingstatic_cast
I write 3 different programs to verify my understandings. Each program is compiled using
g++ -std=c++17 -Wall -Wextra -pedantic
Case #1
int main() {
Foo f;
Bar &b = static_cast<Bar &>(f);
return 0;
}
Code compiles successfully. Running is program will not result in any error
My thoughts: ok, although the actual casting is not right as we are treating a instance of Foo as Bar at runtime, we are not seeing any error because we don't really operate on b
Case #2
int main() {
Foo f;
Bar &b = static_cast<Bar &>(f);
b.bar();
return 0;
}
Code compiles successfully. Running this program will not result in any error, and "bar" is printed
I start to be confused here: why this program ever works and "bar" gets printed? Although here we are treating a Foo as Bar, the underlying instance is still a Foo and it has no method named "bar" defined on it. How could this code works?
Case #3
int main() {
Foo f;
Bar &b = static_cast<Bar &>(f);
b.bar2();
return 0;
}
Code compiles successfully. Running this program will not result in any error, and "bar with 1981882368" (some random number) is printed
I'm even more confused here: if we think in terms of memory layout, the underlying Foo instance has no space reserved for member i
which is defined in Bar. How could this code still works?
Please help me understand the programs above! Thanks in advance!