//12. Директни и индиректни базови класове; конструктури и деструктури //в производни класове. Многократна наследственост. // // Fig. 9.7: point2.h // Definition of class Point #ifndef POINT2_H #define POINT2_H class Point { public: Point( int = 0, int = 0 ); // default constructor ~Point(); // destructor protected: // accessible by derived classes int x, y; // x and y coordinates of Point }; #endif ------ // Fig. 9.7: point2.cpp // Member function definitions for class Point #include #include "point2.h" // Constructor for class Point Point::Point( int a, int b ) { x = a; y = b; cout << "Point constructor: " << '[' << x << ", " << y << ']' << endl; } // Destructor for class Point Point::~Point() { cout << "Point destructor: " << '[' << x << ", " << y << ']' << endl; } ---------------------- // Fig. 9.7: circle2.h // Definition of class Circle #ifndef CIRCLE2_H #define CIRCLE2_H #include "point2.h" class Circle : public Point { public: // default constructor Circle( double r = 0.0, int x = 0, int y = 0 ); ~Circle(); private: double radius; }; #endif ------ // Fig. 9.7: circle2.cpp // Member function definitions for class Circle #include "circle2.h" // Constructor for Circle calls constructor for Point Circle::Circle( double r, int a, int b ) : Point( a, b ) // call base-class constructor { radius = r; // should validate cout << "Circle constructor: radius is " << radius << " [" << x << ", " << y << ']' << endl; } // Destructor for class Circle Circle::~Circle() { cout << "Circle destructor: radius is " << radius << " [" << x << ", " << y << ']' << endl; } ------------- // Fig. 9.7: fig09_07.cpp // Demonstrate when base-class and derived-class // constructors and destructors are called. #include #include "point2.h" #include "circle2.h" int main() { // Show constructor and destructor calls for Point { Point p( 11, 22 ); } cout << endl; Circle circle1( 4.5, 72, 29 ); cout << endl; Circle circle2( 10, 5, 5 ); cout << endl; return 0; } -------------------------------------------------------- // Fig. 9.11: base1.h // Definition of class Base1 #ifndef BASE1_H #define BASE1_H class Base1 { public: Base1( int x ) { value = x; } int getData() const { return value; } protected: // accessible to derived classes int value; // inherited by derived class }; #endif ------ // Fig. 9.11: base2.h // Definition of class Base2 #ifndef BASE2_H #define BASE2_H class Base2 { public: Base2( char c ) { letter = c; } char getData() const { return letter; } protected: // accessible to derived classes char letter; // inherited by derived class }; #endif ------ // Fig. 9.11: derived.h // Definition of class Derived which inherits // multiple base classes (Base1 and Base2). #ifndef DERIVED_H #define DERIVED_H #include "base1.h" #include "base2.h" // multiple inheritance class Derived : public Base1, public Base2 { friend ostream &operator<<( ostream &, const Derived & ); public: Derived( int, char, double ); double getReal() const; private: double real; // derived class's private data }; #endif ------ // Fig. 9.11: derived.cpp // Member function definitions for class Derived #include #include "derived.h" // Constructor for Derived calls constructors for // class Base1 and class Base2. // Use member initializers to call base-class constructors Derived::Derived( int i, char c, double f ) : Base1( i ), Base2( c ), real ( f ) { } // Return the value of real double Derived::getReal() const { return real; } // Display all the data members of Derived ostream &operator<<( ostream &output, const Derived &d ) { output << " Integer: " << d.value << "\n Character: " << d.letter << "\nReal number: " << d.real; return output; // enables cascaded calls } -------------------------- // Fig. 9.11: fig09_11.cpp // Driver for multiple inheritance example #include #include "base1.h" #include "base2.h" #include "derived.h" int main() { Base1 b1( 10 ), *base1Ptr = 0; // create Base1 object Base2 b2( 'Z' ), *base2Ptr = 0; // create Base2 object Derived d( 7, 'A', 3.5 ); // create Derived object // print data members of base class objects cout << "Object b1 contains integer " << b1.getData() << "\nObject b2 contains character " << b2.getData() << "\nObject d contains:\n" << d << "\n\n"; // print data members of derived class object // scope resolution operator resolves getData ambiguity cout << "Data members of Derived can be" << " accessed individually:" << "\n Integer: " << d.Base1::getData() << "\n Character: " << d.Base2::getData() << "\nReal number: " << d.getReal() << "\n\n"; cout << "Derived can be treated as an " << "object of either base class:\n"; // treat Derived as a Base1 object base1Ptr = &d; cout << "base1Ptr->getData() yields " << base1Ptr->getData() << '\n'; // treat Derived as a Base2 object base2Ptr = &d; cout << "base2Ptr->getData() yields " << base2Ptr->getData() << endl; return 0; } ----------------------------------------------------