Point3(double bx,double by,double bz):Point1(bx),Point2(by)
{z=bz;}
~Point3 () // деструктор
{ cout << "destructor Point3 done"<<endl;}
void Print ()
{ cout<<" x="<<x<<" y="<<y<<" z="<<z<<endl;}
};
void main()
{
Point3 P(1,2,3);
P.Print(); // 1 2 3
}
ПРИМЕР 6. Множественное наследование. Неопределенность
Пример множественного наследования вида:
Point1 Point2
Point3
В каждом базовом классе есть свой метод Print. В производном классе такой метод отсутствует. При вызове метода Print из базового класса возникает неопределенность!
#include <iostream.h>
class Point1 // объявление 1 базового класса
{
protected: double x;
public:
Point1(double bx=0) // конструктор
{x=bx; }
~Point1 () // деструктор
{ cout << "destructor Point1 done"<<endl;}
void Print ()
{cout <<" x="<<x<<endl;}
};
class Point2 // объявление 2 базового класса
{ protected: double y;
public:
Point2(double by) // конструктор
{y=by;}
~Point2 () // деструктор
{ cout << "destructor Point2 done"<<endl;}
void Print ()
{cout <<" y="<<y<<endl;}
};
class Point3: public Point1, public Point2
{ double z;
public:
// конструктор вызывает конструкторы 2 базовых классов
Point3(double bx,double by,double bz):Point1(bx),Point2(by)
{z=bz;}
~Point3 () // деструктор
{ cout << "destructor Point3 done"<<endl;}
void Print3 ()
{ cout<<" z="<<z<<endl;}
};
void main()
{
Point3 P(1,2,3);
// P.Print(); // !!! неопределенность
P.Point1::Print(); // 1
P.Point2::Print(); // 2
P.Print3(); // 3
}
ПРИМЕР 7. Полиморфизм. Переопределение метода
Базовый класс имеет метод Print. Производный класс имеет свой метод Print. Поля базового класса имеют доступ protected.
#include <iostream.h>
class Point1 // объявление класса
{ protected: double x,y;
public:
Point1(double bx=0, double by=0) // конструктор
{x=bx; y=by; }
~Point1 () // деструктор
{ cout << "destructor Point1 done"<<endl;}
void Print ()
{cout <<" x="<<x<<" y="<<y<<endl;}
};
class Point2: public Point1 // объявление класса наследника
{ // по умолчанию спецификатор доступа private
double z;
public:
Point2(double bx,double by, double bz):Point1(bx,by) // конструктор
{z=bz;}
~Point2 () // деструктор
{ cout << "destructor Point2 done"<<endl;}
// метод переопределен: обращение к полям базового класса
void Print ()
{ cout<<" x="<<x<<" y="<<y<<" z="<<z<<endl;}
};
void main()
{
Point1 P1(1,2);
P1.Print(); // 1 2
Point2 P2(1,2,3);
P2.Print(); // 1 2 3
P3.Point1::Print(); // 1 2 !!! вызов метода базового класса
}
ПРИМЕР 8. Динамические объекты через указатель на базовый класс.
Два производных класса от одного базового.
Point1
Point2 Point3
В каждом классе свой метод Print.
В главной программе определим динамические объекты, через указатель на базовый класс. При вызове метода Print для объектов производных классов, происходит вызов метода базового (!) класса.
#include <iostream.h>
class Point1 // объявление базового класса
{ protected:
double x,y;
public:
Point1(double bx=0, double by=0) // конструктор
{x=bx; y=by; }
~Point1 () // деструктор
{ cout << "destructor Point1 done"<<endl;}
void Print ()
{cout <<" x="<<x<<" y="<<y<<endl;}
};
class Point2: public Point1 // объявление класса наследника
{ double z; // новое поле
public:
Point2(double bx,double by, double bz):Point1(bx,by) // конструктор
{z=bz;}
~Point2 () // деструктор
{ cout << "destructor Point2 done"<<endl;}
// метод переопределен
void Print ()
{ cout<<" x="<<x<<" y="<<y<<" z="<<z<<endl;}
};
class Point3: public Point1 // объявление класса наследника
{ int a,b; // новые поля
public:
Point3(double bx,double by, int ba,int bb):Point1(bx,by) // конструктор
{a=ba;b=bb;}
~Point3 () // деструктор
{ cout << "destructor Point3 done"<<endl;}
// метод переопределен
void Print ()
{ cout<<" x="<<x<<" y="<<y<<" a="<<a<<" b="<<b<<endl;}
};
void main()
{
Point1* P;
P=new Point1(1,2);
P->Print(); // 1 2
// Указатель на базовый класс совместим с указателем на производный класс.
P=new Point2(3,4,5);
P->Print(); // 3 4 !!!
// Указатель на базовый класс совместим с указателем на производный класс.
P=new Point3(6,7,8,9); //
P->Print(); // 6 7 !!!
}
ПРИМЕР 9. Динамические объекты через указатель на базовый класс. Виртуальные функции
Пример тот же. Добавляем одно слово virtual для метода Print базового класса!
Для каждого объекта производных классов вызывается свой метод Print.
#include <iostream.h>
class Point1 // объявление базового класса
{ protected:
double x,y;
public:
Point1(double bx=0, double by=0) // конструктор
{x=bx; y=by; }
~Point1 () // деструктор
{ cout << "destructor Point1 done"<<endl;}
virtual void Print ()
{cout <<" x="<<x<<" y="<<y<<endl;}
};
class Point2: public Point1 // объявление класса наследника
{ double z; // новое поле
public:
Point2(double bx,double by, double bz):Point1(bx,by) // конструктор
{z=bz;}
~Point2 () // деструктор
{ cout << "destructor Point2 done"<<endl;}
// метод переопределен
/* virtual */ void Print ()
{ cout<<" x="<<x<<" y="<<y<<" z="<<z<<endl;}
};
class Point3: public Point1 // объявление класса наследника
{ int a,b; // новые поля
public:
Point3(double bx,double by, int ba,int bb):Point1(bx,by) // конструктор
{a=ba;b=bb;}
~Point3 () // деструктор
{ cout << "destructor Point3 done"<<endl;}
// метод переопределен
/* virtual */ void Print ()
{ cout<<" x="<<x<<" y="<<y<<" a="<<a<<" b="<<b<<endl;}
};
void main()
{
Point1* P;
P=new Point1(1,2);
P->Print(); // 1 2
// Указатель на базовый класс совместим с указателем на производный класс.
P=new Point2(3,4,5);
P->Print(); // 3 4 5 !!!
// Указатель на базовый класс совместим с указателем на производный класс.
P=new Point3(6,7,8,9);
P->Print(); // 6 7 8 9 !!!
}
ПРИМЕР 10. Абстрактный класс
Пример тот же. Базовый класс – абстрактный.
#include <iostream.h>
class Point // объявление абстрактного класса
{
public:
Point() {} // конструктор
~Point () {} // деструктор
virtual void Print() =0; // чистая виртуальная функция
};
class Point1: public Point // объявление производного класса
{ protected: double x;
public:
Point1(double bx) {x=bx;} // конструктор
~Point1 () // деструктор
{ cout << "destructor Point1 done"<<endl;}
void Print () {cout <<" x="<<x<<endl;}
};
class Point2: public Point1 // объявление производного класса
{ double y;
public:
Point2(double bx,double by):Point1(bx) {y=by;} // конструктор
~Point2 () // деструктор
{ cout << "destructor Point2 done"<<endl;}
void Print() {cout <<" x= "<<x<<" y="<<y<<endl;}
};
void main()
{ Point* P;
// P=new Point(); // !!! нельзя создать объект абстрактного класса
// P->Print();
P=new Point1(1);
P->Print(); // 1
P=new Point2(2,3);
P->Print(); // 2 3
}
ПРИМЕР 11. Вызов метода производного класса из метода базового класса
Два производных класса от одного базового.
Point1
Point2 Point3
В каждом классе свой метод Print, который должен вызываться из метода Print_B базового класса.
Но при вызове метода Print для объектов производных классов, происходит вызов метода Print базового (!) класса.
#include <iostream.h>
class Point1 // объявление базового класса
{ protected:
double x,y;
public:
Point1(double bx=0, double by=0) // конструктор
{x=bx; y=by; }
~Point1 () // деструктор
{ cout << "destructor Point1 done"<<endl;}
// вызов метода Print из метода Print_B
void Print_B()
{cout <<" base class "<<endl;
Print(); }
void Print ()
{cout <<" x="<<x<<" y="<<y<<endl;}
};
class Point2: public Point1 // объявление класса наследника
{ double z; // новое поле
public:
Point2(double bx,double by, double bz):Point1(bx,by) // конструктор
{z=bz;}
~Point2 () // деструктор
{ cout << "destructor Point2 done"<<endl;}
// метод переопределен
void Print ()
{ cout<<" x="<<x<<" y="<<y<<" z="<<z<<endl;}
};
class Point3: public Point1 // объявление класса наследника
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.