Last active
June 8, 2018 11:11
-
-
Save nmmmnu/c75204c9c1f9c49bf8575fa721dfd062 to your computer and use it in GitHub Desktop.
Hand made polymorphism in C++11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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