Skip to content

Instantly share code, notes, and snippets.

@nmmmnu
Last active June 8, 2018 11:11
Show Gist options
  • Save nmmmnu/c75204c9c1f9c49bf8575fa721dfd062 to your computer and use it in GitHub Desktop.
Save nmmmnu/c75204c9c1f9c49bf8575fa721dfd062 to your computer and use it in GitHub Desktop.
Hand made polymorphism in C++11
#include <cstdio>
// ==========================================
template<class T>
struct VTableFor;
// ==========================================
struct Vehicle{
void *ptr;
const VTableFor<Vehicle> *vptr;
template<class T>
Vehicle(T *ptr) : ptr(ptr), vptr(& T::vtable__){}
template<class T>
Vehicle(T &ptr) : Vehicle(&ptr){}
void accelerate();
};
template<>
struct VTableFor<Vehicle>{
void (*accelerate)(void *ptr);
};
inline void Vehicle::accelerate(){
vptr->accelerate(ptr);
}
// ==========================================
struct Car{
Car(const char *name) : name(name){}
const char *name;
static const VTableFor<Vehicle> vtable__;
};
const VTableFor<Vehicle> Car::vtable__{
[](void *ptr){
printf("Car::accelerate, Name : %s\n", reinterpret_cast<Car *>(ptr)->name);
}
};
// ==========================================
struct Truck{
Truck(int const tonnage) : tonnage(tonnage){}
int tonnage;
static const VTableFor<Vehicle> vtable__;
};
const VTableFor<Vehicle> Truck::vtable__{
[](void *ptr){
printf("Truck::accelerate, Tonnage: %d\n", reinterpret_cast<Truck *>(ptr)->tonnage);
}
};
// ==========================================
#include <vector>
void acc(Vehicle x){
x.accelerate();
}
int main(){
Car bmw("BMW");
Truck t100(100);
acc(bmw);
acc(t100);
}
#include <cstdio>
// ==========================================
template<class T>
struct VTableFor;
// ==========================================
struct Vehicle{
void *ptr;
const VTableFor<Vehicle> *vptr;
template<class T>
constexpr Vehicle(T *ptr) : ptr(ptr), vptr(& T::vtable__){}
template<class T>
constexpr Vehicle(T &ptr) : Vehicle(&ptr){}
void accelerate();
};
template<>
struct VTableFor<Vehicle>{
void (*accelerate)(void *ptr);
};
inline void Vehicle::accelerate(){
vptr->accelerate(ptr);
}
// ==========================================
struct Car{
constexpr Car(const char *name) : name(name){}
const char *name;
static void accelerate__(void *ptr){
printf("Car::accelerate, Name : %s\n", reinterpret_cast<Car *>(ptr)->name);
}
static constexpr VTableFor<Vehicle> vtable__ = {
Car::accelerate__
};
};
constexpr VTableFor<Vehicle> Car::vtable__;
// ==========================================
struct Truck{
constexpr Truck(int const tonnage) : tonnage(tonnage){}
int tonnage;
static void accelerate__(void *ptr){
printf("Truck::accelerate, Tonnage: %d\n", reinterpret_cast<Truck *>(ptr)->tonnage);
}
static constexpr VTableFor<Vehicle> vtable__{
Truck::accelerate__
};
};
constexpr VTableFor<Vehicle> Truck::vtable__;
// ==========================================
#include <vector>
void acc(Vehicle x){
x.accelerate();
}
int main(){
Car bmw("BMW");
Truck t100(100);
acc(bmw);
acc(t100);
}
#include <cstdio>
// ==========================================
struct Vehicle{
virtual void accelerate() = 0;
};
// ==========================================
struct Car : Vehicle{
Car(const char *name) : name(name){}
const char *name;
void accelerate() override{
printf("V Car::accelerate, Name : %s\n", this->name);
}
};
// ==========================================
struct Truck : Vehicle{
Truck(int const tonnage) : tonnage(tonnage){}
int tonnage;
void accelerate() override{
printf("V Truck::accelerate, Tonnage: %d\n", this->tonnage);
}
};
// ==========================================
#include <vector>
void acc(Vehicle &x){
x.accelerate();
}
int main(){
Car bmw("BMW");
Truck t100(100);
acc(bmw);
acc(t100);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment