#include #include #include // C-like: // class OPOD { // public: // ~OPOD() { // undefined behavior // delete (T*)a; delete (U*)b; // UB // } // OPOD(void *p1, void *p2) : a{p1}, b{p2} {} // private: // void *a{}; // void *b{}; // }; // C++ static polymorphism: // template class POD { // public: // ~POD() = default; // dtor // POD() = default; // default ctor // POD(const POD&) = default; // POD(POD&&) noexcept = default; // POD& operator=(const POD&) = default; // POD& operator=(POD&&) = default; // private: // T a{}; // U b{}; // }; /* // C++: dynamic polymorphism struct Type { virtual ~Type() {} virtual Type& operator=(const Type&) = 0; }; struct Int : public Type { Type& operator=(const Type& other) override { auto t = dynamic_cast(&other); // UB: actual type of other unknown x = t->x; return *this; } private: int x{}; }; struct Char : public Type { Type& operator=(const Type&) override { return *this; } private: char x{}; }; class POD { public: ~POD() = default; // dtor POD() = default; // default ctor POD(const POD&) = default; POD(POD&&) noexcept = default; POD& operator=(const POD&) = default; POD& operator=(POD&&) = default; POD(Type *p1, Type *p2) : a{p1}, b{p2} {} private: Type* a{}; Type* b{}; }; */ // C++ dynamic polymorphism: using Type = std::variant; class POD { public: ~POD() = default; // dtor POD() = default; // default ctor POD(const POD&) = default; POD(POD&&) noexcept = default; POD& operator=(const POD&) = default; POD& operator=(POD&&) = default; POD(auto x, auto y) : a{x}, b{y} {} private: Type a{}; Type b{}; }; int main() { POD x{4, "hello"}; }