C++
Beginner
1 min read
Virtual Functions and the vtable
Example
#include <iostream>
#include <memory>
#include <vector>
#include <cmath>
class Shape {
public:
virtual ~Shape() = default;
// Pure virtual — every concrete shape must implement this
virtual double area() const = 0;
virtual double perimeter() const = 0;
virtual std::string describe() const = 0;
// Non-virtual template method uses virtual helpers
void report() const {
std::cout << describe()
<< " area=" << area()
<< " perimeter=" << perimeter() << "\n";
}
};
class Circle final : public Shape {
public:
explicit Circle(double r) : r_(r) {}
double area() const override { return M_PI * r_ * r_; }
double perimeter() const override { return 2 * M_PI * r_; }
std::string describe() const override { return "Circle(r=" + std::to_string(r_) + ")"; }
private:
double r_;
};
class Rectangle : public Shape {
public:
Rectangle(double w, double h) : w_(w), h_(h) {}
double area() const override { return w_ * h_; }
double perimeter() const override { return 2 * (w_ + h_); }
std::string describe() const override {
return "Rect(" + std::to_string(w_) + "x" + std::to_string(h_) + ")";
}
private:
double w_, h_;
};
int main() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(5.0));
shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));
for (const auto& s : shapes)
s->report(); // virtual dispatch selects correct overrides
return 0;
}