// Multiple Inheritance with Virtual Base classes #include #include #include #include using namespace std; class Quadrilateral { protected: double a, b, c, d; public: Quadrilateral(double s1, double s2, double s3, double s4) : a(s1), b(s2), c(s3), d(s4) {} Quadrilateral() = default; virtual string type() const; friend ostream& operator<<(ostream&, const Quadrilateral&); }; string Quadrilateral::type() const { string quadname = typeid(*this).name(); #ifdef _MSC_VER // for MS Visual Studio quadname = quadname.substr(6); #else // for other compilers quadname = quadname.substr(quadname.find_first_not_of("0123456789")); #endif return quadname; } ostream& operator<<(ostream& out, const Quadrilateral& object) { out << left << setw(21) << (object.type() + ": ") << &object << " sides " << object.a << ' ' << object.b << ' ' << object.c << ' ' << object.d; return out; } class Trapezoid : public Quadrilateral { public: Trapezoid(double base1, double base2, double leg1, double leg2) : Quadrilateral(base1, leg1, base2, leg2) {} }; class IsoscelesTrapezoid : public Trapezoid { public: IsoscelesTrapezoid(double base1, double base2, double leg) : Trapezoid(base1, leg, base2, leg) {} }; class Parallelogram : public Quadrilateral { protected: int angle; public: Parallelogram(double s1, double s2, int ang) : Quadrilateral(s1, s2, s1, s2), angle(ang) { } Parallelogram() : angle(0) { } friend ostream& operator<<(ostream& out, const Parallelogram& object); }; ostream& operator<<(ostream& out, const Parallelogram& object) { // first call the Quadrilateral insertion operator out << static_cast(object); // the print the angles out << " angles = " << object.angle << ' ' << (180 - object.angle); return out; } class Rectangle : virtual public Parallelogram { public: Rectangle(double base, double height) : Parallelogram(base, height, 90) {} Rectangle() {} }; class Rhombus : virtual public Parallelogram { public: Rhombus(double side, int ang) : Parallelogram(side, side, ang) {} Rhombus() {} }; class Square : public Rhombus, public Rectangle { public: Square(double side) : Parallelogram(side, side, 90) {} }; int main(void) { Quadrilateral q1(1, 2, 3, 4); cout << q1 << endl; Trapezoid q2(22, 13, 8, 15); cout << q2 << endl; IsoscelesTrapezoid q3(18, 8, 13); cout << q3 << endl; Parallelogram q4(4, 3, 45); cout << q4 << endl; Rectangle q5(4, 3); cout << q5 << endl; Rhombus q6(5, 45); cout << q6 << endl; Square q7(5); cout << q7 << endl << endl; // Poylmorphism Quadrilateral* ptrQ; ptrQ = &q1; cout << *ptrQ << endl; ptrQ = &q2; cout << *ptrQ << endl; ptrQ = &q3; cout << *ptrQ << endl; ptrQ = &q4; cout << *ptrQ << endl; ptrQ = &q5; cout << *ptrQ << endl; ptrQ = &q6; cout << *ptrQ << endl; ptrQ = &q7; cout << *ptrQ << endl; Parallelogram* ptrP; ptrP = dynamic_cast(ptrQ); if (ptrP) cout << *ptrP << endl; }