Лекция 6. Наследование
Класс Вектор
#include <iostream.h>
class vector{
int n; // Размерность пространства
int* mas; // координаты вектора
static int count;
public:
static void inc_count(){ count++; }
static void dec_count(){ count--; }
vector(int razm){
n=razm;
mas=new int[n];
for (int i=0;i<n;i++)
mas[i]=0;
inc_count();
};
~vector(){dec_count();} // деконструктор
inline int size(){return n;};
friend ostream& operator<< (ostream& os, vector const v);
int operator [] (int index){return mas[index];};
vector* prisv(int index, int znach){mas[index]=znach; return this;};
vector* add(vector* a, vector* b);
vector* sub(vector* a, vector* b);
int dotprod(vector* a, vector* b);
friend vector& operator ++(vector& v);
vector operator ++(int){vector v(n);for (int i=0;i<n;i++) mas[i]++;return v;};
bool operator >(const vector &v){
int dl=0,dl2=0;
for (int i=0;i<n;i++)dl+=mas[i]*mas[i];
for (int i=0;i<v.n;i++)dl2+=v.mas[i]*v.mas[i];
if (dl>dl2) return true;
return false;
};
const vector& operator = (const vector &v){
// проверка на самоприсваивание
if (&v==this)return *this;
n=v.n;
for (int i=0;i<n;i++) mas[i]=v.mas[i];
return *this;
};
};
int vector::count=0;
vector& operator ++(vector& v){for (int i=0;i<v.n;i++) ++v.mas[i];return v;};
ostream& operator<< (ostream& os, vector const v){
cout<<endl<<"vector: ";
for (int i=0;i<v.n;i++)
cout<<v.mas[i]<<' ';
cout<<endl;
return os;
};
vector* vector::add(vector* a, vector* b){
|
|
if (a->n==b->n)
for (int i=0;i<a->n;i++)
mas[i]=a->mas[i]+b->mas[i];
return this;
};
vector* vector::sub(vector* a, vector* b){
if (a->n==b->n)
for (int i=0;i<a->n;i++)
mas[i]=a->mas[i]-b->mas[i];
return this;
};
int vector::dotprod(vector* a, vector* b){
int pr=0;
if (a->n==b->n)
for (int i=0;i<a->n;i++)
pr=pr+a->mas[i]*b->mas[i];
return pr;
};
int main(int argc, char* argv[])
{
int n=3;
vector a(n),b(n);
a.prisv(0,1); a.prisv(1,2);a.prisv(2,3);
cout<<a;
b.prisv(0,4); b.prisv(1,5);b.prisv(2,6);
cout<<b;
a.add(&a,&b); cout<<a;
a.sub(&a,&b); cout<<a;
int d=a.dotprod(&a,&b); cout<<"pr="<<d<<" ";
int c;
cout<<a.size();
cout<<a[2];
cout<<endl<<a++;
if (a>b) cout<<"true"; else cout<<"false";
vector vv(n);
vv=a;
cout<<vv;
cin>>c;
return 0;
}
Важнейшим свойством объектно-ориентированного программирования является наследование. Наследование – это способ повторного использования программного обеспечения, при котором новые производные классы (наследники) создаются на базе уже существующих базовых классов (родителей). При создании новый класс является наследником членов и методов ранее определенного базового класса. Создаваемый путем наследования класс является производным (derived class), который в свою очередь может выступать в качестве базового класса (based class) для создаваемых классов. Если имена методов производного и базового классов совпадают, то методы производного класса перегружают методы базового класса.
При описании класса в его заголовке перечисляются все классы, являющиеся для него базовыми. Возможность обращения к элементам этих классов регулируется с помощью модификаторов наследования private, protected и public:
class имя: [private | protected | public] базовый_класс{тело класса};
Если базовых классов несколько, они перечисляются через запятую. Перед каждым может стоять свой модификатор наследования. По умолчанию он private.
|
|
Если задан модификатор наследования public, наследование называется открытым. Использование модификатора protected делает наследование защищенным, а модификатора private - закрытым.
До сих пор мы рассматривали только спецификаторы доступа private и public, применяемые к элементам класса. Для любого элемента класса может также использоваться спецификатор protected, который для одиночных классов, не входящих в иерархию, равносилен private. Разница между ними проявляется при наследовании. Возможные сочетания модификаторов и спецификаторов доступа приведены в таблице:
Модификатор наследования | Спецификатор базового класса | Доступ в производном классе |
private | private protected public | нет private private |
protected | private protected public | нет protected protected |
public | private protected public | нет protected public |
Как видно из таблицы, private элементы базового класса в производном классе недоступны вне зависимости от ключа. Обращение к ним может осуществляться только через методы базового класса.
Элементы protected при наследовании с ключом private становятся в производном классе private, в остальных случаях права доступа к ним не изменяются.
Доступ к элементам public при наследовании становится соответствующим ключу доступа.
Если базовый класс наследуется с ключом private, можно выборочно сделать некоторые его элементы доступными в производном классе, объявив их в секции public производного класса с помощью операции доступа к области видимости:
class Base{...
public: void f();};
class Derived: private Base{...
public: Base::void f();};