Inheritance
Virtual Functions
Virtual functions let a base pointer call the derived class implementation.
virtual
A `virtual` function can dispatch through a base pointer or reference at runtime.
Virtual Functions
virtual_functions.cpp
Replay: real traced execution (multi-file project)
#include <iostream>
#include <string>
class Shape {
public:
virtual int measure() {
return 0;
}
virtual std::string name() {
return "shape";
}
};
class Square : public Shape {
private:
int side;
public:
Square(int size) {
side = size;
}
int measure() override {
return side * side;
}
std::string name() override {
return "square";
}
};
class Line : public Shape {
private:
int length;
public:
Line(int size) {
length = size;
}
int measure() override {
return length;
}
std::string name() override {
return "line";
}
};
int main() {
bool useSquare = true;
int size = 4;
Square square(size);
Line line(size);
Shape* shape = &line;
if (useSquare) {
shape = □
}
std::cout << "shape=" << shape->name() << std::endl;
std::cout << "measure=" << shape->measure() << std::endl;
return 0;
}
#include <iostream>
#include <string>
class Shape {
public:
virtual int measure() {
return 0;
}
virtual std::string name() {
return "shape";
}
};
class Square : public Shape {
private:
int side;
public:
Square(int size) {
side = size;
}
int measure() override {
return side * side;
}
std::string name() override {
return "square";
}
};
class Line : public Shape {
private:
int length;
public:
Line(int size) {
length = size;
}
int measure() override {
return length;
}
std::string name() override {
return "line";
}
};
int main() {
bool useSquare = false;
int size = 4;
Square square(size);
Line line(size);
Shape* shape = &line;
if (useSquare) {
shape = □
}
std::cout << "shape=" << shape->name() << std::endl;
std::cout << "measure=" << shape->measure() << std::endl;
return 0;
}
#include <iostream>
#include <string>
class Shape {
public:
virtual int measure() {
return 0;
}
virtual std::string name() {
return "shape";
}
};
class Square : public Shape {
private:
int side;
public:
Square(int size) {
side = size;
}
int measure() override {
return side * side;
}
std::string name() override {
return "square";
}
};
class Line : public Shape {
private:
int length;
public:
Line(int size) {
length = size;
}
int measure() override {
return length;
}
std::string name() override {
return "line";
}
};
int main() {
bool useSquare = true;
int size = 2;
Square square(size);
Line line(size);
Shape* shape = &line;
if (useSquare) {
shape = □
}
std::cout << "shape=" << shape->name() << std::endl;
std::cout << "measure=" << shape->measure() << std::endl;
return 0;
}
#include <iostream>
#include <string>
class Shape {
public:
virtual int measure() {
return 0;
}
virtual std::string name() {
return "shape";
}
};
class Square : public Shape {
private:
int side;
public:
Square(int size) {
side = size;
}
int measure() override {
return side * side;
}
std::string name() override {
return "square";
}
};
class Line : public Shape {
private:
int length;
public:
Line(int size) {
length = size;
}
int measure() override {
return length;
}
std::string name() override {
return "line";
}
};
int main() {
bool useSquare = true;
int size = 6;
Square square(size);
Line line(size);
Shape* shape = &line;
if (useSquare) {
shape = □
}
std::cout << "shape=" << shape->name() << std::endl;
std::cout << "measure=" << shape->measure() << std::endl;
return 0;
}
useSquare ← 1, size ← 4
51int main() {52 bool useSquare→ 1 = true; //@useSquare=false53 int size→ 4 = 4; //@size=2, 65455 Square square(size4);56 Line line(size);side ← 4
19public:20 Square(int size4) {21 side→ 4 = size4;22 }square ← (empty)
55Square square→ (empty)(size4);56Line line(size4);57Shape* shape = &line;length ← 4
37public:38 Line(int size4) {39 length→ 4 = size4;40 }line ← (empty), shape ← ⟨addr A⟩
55Square square(size);56Line line→ (empty)(size4);57Shape* shape→ ⟨addr A⟩ = &line(empty);shape ← ⟨addr B⟩
59if (useSquare1) {60 shape→ ⟨addr B⟩ = &square(empty);61}std::cout << "shape=" << shape->name() << std::endl;
63std::cout << "shape=" << shape⟨addr B⟩->name() << std::endl;64std::cout << "measure=" << shape->measure() << std::endl;std::cout << "shape=" << shape->name() << std::endl;
63std::cout << "shape=" << shape⟨addr B⟩->name() << std::endl;64std::cout << "measure=" << shape⟨addr B⟩->measure() << std::endl;65return 0;outputshape=squareint measure() override
24int measure() override {25 return side4 * side;26}std::cout << "measure=" << shape->measure() << std::endl;
63 std::cout << "shape=" << shape->name() << std::endl;64 std::cout << "measure=" << shape⟨addr B⟩->measure() << std::endl;65 return 0;66}outputmeasure=16
useSquare ← 0, size ← 4
51int main() {52 bool useSquare→ 0 = false;53 int size→ 4 = 4;5455 Square square(size4);56 Line line(size);side ← 4
19public:20 Square(int size4) {21 side→ 4 = size4;22 }square ← (empty)
55Square square→ (empty)(size4);56Line line(size4);57Shape* shape = &line;length ← 4
37public:38 Line(int size4) {39 length→ 4 = size4;40 }line ← (empty), shape ← ⟨addr A⟩
55Square square(size);56Line line→ (empty)(size4);57Shape* shape→ ⟨addr A⟩ = &line(empty);5859if (useSquare) {60 shape = □61}6263std::cout << "shape=" << shape⟨addr A⟩->name() << std::endl;64std::cout << "measure=" << shape->measure() << std::endl;std::cout << "shape=" << shape->name() << std::endl;
63std::cout << "shape=" << shape⟨addr A⟩->name() << std::endl;64std::cout << "measure=" << shape⟨addr A⟩->measure() << std::endl;65return 0;outputshape=lineint measure() override
42int measure() override {43 return length4;44}std::cout << "measure=" << shape->measure() << std::endl;
63 std::cout << "shape=" << shape->name() << std::endl;64 std::cout << "measure=" << shape⟨addr A⟩->measure() << std::endl;65 return 0;66}outputmeasure=4
useSquare ← 1, size ← 2
51int main() {52 bool useSquare→ 1 = true;53 int size→ 2 = 2;5455 Square square(size2);56 Line line(size);side ← 2
19public:20 Square(int size2) {21 side→ 2 = size2;22 }square ← (empty)
55Square square→ (empty)(size2);56Line line(size2);57Shape* shape = &line;length ← 2
37public:38 Line(int size2) {39 length→ 2 = size2;40 }line ← (empty), shape ← ⟨addr A⟩
55Square square(size);56Line line→ (empty)(size2);57Shape* shape→ ⟨addr A⟩ = &line(empty);shape ← ⟨addr B⟩
59if (useSquare1) {60 shape→ ⟨addr B⟩ = &square(empty);61}std::cout << "shape=" << shape->name() << std::endl;
63std::cout << "shape=" << shape⟨addr B⟩->name() << std::endl;64std::cout << "measure=" << shape->measure() << std::endl;std::cout << "shape=" << shape->name() << std::endl;
63std::cout << "shape=" << shape⟨addr B⟩->name() << std::endl;64std::cout << "measure=" << shape⟨addr B⟩->measure() << std::endl;65return 0;outputshape=squareint measure() override
24int measure() override {25 return side2 * side;26}std::cout << "measure=" << shape->measure() << std::endl;
63 std::cout << "shape=" << shape->name() << std::endl;64 std::cout << "measure=" << shape⟨addr B⟩->measure() << std::endl;65 return 0;66}outputmeasure=4
useSquare ← 1, size ← 6
51int main() {52 bool useSquare→ 1 = true;53 int size→ 6 = 6;5455 Square square(size6);56 Line line(size);side ← 6
19public:20 Square(int size6) {21 side→ 6 = size6;22 }square ← (empty)
55Square square→ (empty)(size6);56Line line(size6);57Shape* shape = &line;length ← 6
37public:38 Line(int size6) {39 length→ 6 = size6;40 }line ← (empty), shape ← ⟨addr A⟩
55Square square(size);56Line line→ (empty)(size6);57Shape* shape→ ⟨addr A⟩ = &line(empty);shape ← ⟨addr B⟩
59if (useSquare1) {60 shape→ ⟨addr B⟩ = &square(empty);61}std::cout << "shape=" << shape->name() << std::endl;
63std::cout << "shape=" << shape⟨addr B⟩->name() << std::endl;64std::cout << "measure=" << shape->measure() << std::endl;std::cout << "shape=" << shape->name() << std::endl;
63std::cout << "shape=" << shape⟨addr B⟩->name() << std::endl;64std::cout << "measure=" << shape⟨addr B⟩->measure() << std::endl;65return 0;outputshape=squareint measure() override
24int measure() override {25 return side6 * side;26}std::cout << "measure=" << shape->measure() << std::endl;
63 std::cout << "shape=" << shape->name() << std::endl;64 std::cout << "measure=" << shape⟨addr B⟩->measure() << std::endl;65 return 0;66}outputmeasure=36