Created
February 28, 2024 18:36
-
-
Save mshafae/00875dc88635dfb640278b2259b19fb3 to your computer and use it in GitHub Desktop.
CPSC 120 C++ virtual usage
This file contains hidden or 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
// Gist https://gist.github.com/mshafae/00875dc88635dfb640278b2259b19fb3 | |
// Filename cpsc120_virtual.cc | |
// CompileCommand clang++ -std=c++17 cpsc120_virtual.cc | |
// Demonstrates how virtual works in C++ | |
#include <iostream> | |
#include <string> | |
class Fizz { | |
public: | |
virtual void PureVirtual() = 0; | |
void FavoriteColor() { std::cout << "Red " << this << "\n"; } | |
void FavoriteSeason() { std::cout << "Winter " << this << "\n"; } | |
}; | |
class Buzz : public Fizz { | |
public: | |
void FavoriteColor() { std::cout << "Fall " << this << "\n"; } | |
}; | |
class Frob : public Buzz { | |
public: | |
void PureVirtual() { std::cout << "Not so pure anymore " << this << "\n"; } | |
void FavoriteColor() { std::cout << "Blue " << this << "\n"; } | |
// No FavoriteSeason() | |
}; | |
class Foo { | |
public: | |
virtual void SayHi() { std::cout << "Foo saying hi " << this << "\n"; } | |
void MyName() { std::cout << "My name is Foo " << this << "\n"; } | |
}; | |
class Bar : public Foo { | |
public: | |
void SayHi() { std::cout << "Bar saying hi " << this << "\n"; } | |
void MyName() { std::cout << "My name is Bar " << this << "\n"; } | |
}; | |
int main(int argc, char* argv[]) { | |
// error: variable type 'Fizz' is an abstract class | |
// unimplemented pure virtual method 'PureVirtual' in 'Fizz' | |
// Fizz x; | |
// error: variable type 'Buzz' is an abstract class | |
// unimplemented pure virtual method 'PureVirtual' in 'Buzz' | |
// Buzz x; | |
// We can define Frob because PureVirtual is defined. | |
Frob x; | |
// We expect "Not so pure anymore." | |
x.PureVirtual(); | |
// We expect "Green" | |
x.FavoriteColor(); | |
// We expect "Fall" | |
x.FavoriteSeason(); | |
std::cout << "\n"; | |
Foo f; | |
Bar b; | |
// We expect "My name is Foo" | |
f.MyName(); | |
// We expect "Foo saying hi" | |
f.SayHi(); | |
// We expect "My name is Bar" | |
b.MyName(); | |
// We expect "Bar saying hi" | |
b.SayHi(); | |
std::cout << "\n"; | |
Foo* ptr; | |
ptr = &f; | |
// We expect "My name is Foo" | |
ptr->MyName(); | |
// We expect "Foo saying hi" | |
ptr->SayHi(); | |
// We use the parent type's pointer to point to the derived type. | |
// Pointers can be re-assigned. | |
ptr = &b; | |
// We expect "My name is Bar" but we see "My name is Foo" | |
ptr->MyName(); | |
// We expect "Bar saying hi". | |
ptr->SayHi(); | |
std::cout << "\n"; | |
Foo& ref_f = f; | |
// We expect "My name is Foo" | |
f.MyName(); | |
// We expect "Foo saying hi" | |
ref_f.SayHi(); | |
// References can only be bound once, so we need a new one. | |
Foo& ref_b = b; | |
// We expect "My name is Bar" but we see "My name is Foo" | |
ref_b.MyName(); | |
// We use the parent type's reference to alias the derived type | |
// instance. We expect "Bar saying hi". | |
ref_b.SayHi(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment