Classic Virtual¶
Overview¶
Classic polymorpism: common base class - interface
Virtual dispatch per language support (this is what
virtual
is there for)Type erasure: not seeing derived types (a.k.a. concrete types) across the program - only the interface
Easy to use: call base class pointer ⟶ dynamic dispatch
Pro: easy polymorphic use (e.g. store object of different derived type in an array of pointer-to-base-type)
Con: code bloat, measured in binary size
Sensor Definitions¶
#pragma once
class Sensor
{
public:
virtual ~Sensor() = default;
virtual double get_temperature() = 0;
};
class Sensor1 : public Sensor
{
public:
Sensor1(double temperature) : _temperature{temperature} {}
double get_temperature() override { return _temperature; }
private:
double _temperature;
};
class Sensor2 : public Sensor
{
public:
Sensor2(double temperature) : _temperature{temperature} {}
double get_temperature() override { return _temperature; }
private:
double _temperature;
};
Virtual Access¶
This is easy - just call virtual method …
#pragma once
static inline double get_temperature(Sensor* s)
{
return s->get_temperature();
}
Average Across Many¶
#pragma once
#include "virtual.h"
double average(auto& sensors) // <--- abbreviated function template
{
double sum = 0;
unsigned long num = 0;
for (auto& s: sensors) {
++num;
sum += get_temperature(s);
}
return sum/num;
}
Main Program¶
#include "sensors.h"
#include "avg.h"
#include <iostream>
int main()
{
Sensor1 s1{37.1};
Sensor2 s2{42.666};
Sensor* sensors[] = {&s1, &s2};
std::cout << average(sensors) << std::endl;
return 0;
}