Unrelated (Duck-Typed)¶
Overview¶
Alternative to common base class …
… which is too much writing
⟶ Good ol’ C
union
(Pointer-only though)
Manual virtual dispatch (see
code/unrelated/virtual.h
):switch
based on type field.
Sensor Definitions¶
#pragma once
class Sensor1
{
public:
Sensor1(double temperature)
: _temperature{temperature} {}
double get_temperature() { return _temperature; }
private:
double _temperature;
};
class Sensor2
{
public:
Sensor2(double temperature)
: _temperature{temperature} {}
double get_temperature() { return _temperature; }
private:
double _temperature;
};
struct SensorPtr
{
enum Type
{
SENSOR1,
SENSOR2,
};
union variant
{
Sensor1* s1;
Sensor2* s2;
};
SensorPtr(Sensor1* s) { type = SENSOR1; variant.s1 = s; }
SensorPtr(Sensor2* s) { type = SENSOR2; variant.s2 = s; }
Type type;
variant variant;
};
Virtual Access¶
#pragma once
#include "sensors.h"
static inline double get_temperature(SensorPtr s)
{
switch (s.type) {
case SensorPtr::SENSOR1: {
Sensor1* s1 = s.variant.s1;
return s1->get_temperature();
}
case SensorPtr::SENSOR2: {
Sensor2* s2 = s.variant.s2;
return s2->get_temperature();
}
}
return -273.15; // <--- never reached
}
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};
SensorPtr sensors[] = {&s1, &s2};
std::cout << average(sensors) << std::endl;
return 0;
}