Статические функции-члены класса имеют доступ только к статическим членам класса. Для доступа к нестатическим членам они должны получить адрес объекта как параметр
#include <iostream.h>
class CBox // объявление класса
{
double m_length; // поле - длина
double m_width; // поле - ширина
double m_height; // поле - высота
static int m_noboxes; // поле - cтатическая переменная
public:
CBox() // конструктор
{m_length=0; m_width=0; m_height=0; m_noboxes++;}
CBox(double l,double w) // перегруженный конструктор
{m_length=l; m_width=w; m_height=0; m_noboxes++;}
CBox(double l, double w, double h) // перегруженный конструктор
{m_length=l; m_width=w; m_height=h; m_noboxes++;}
~CBox () // деструктор
{ cout << "destructor CBox done"<<endl;}
void Set_l(double l) { m_length=l;}
void Set_w(double w) { m_width=w;}
void Set_h(double h) { m_height=h;}
const double Get_l() { return m_length;}
const double Get_w() { return m_width;}
const double Get_h() { return m_height;}
const void Print ()
{cout <<" L="<<m_length<<" W="<<m_width<<" H="<<m_height<<endl;}
const double Volume( ) {return m_length*m_width*m_height;}
// cтатические функции-члены класса имеют доступ
// только к статическим членам класса.
static int Getnoboxes() {return m_noboxes;}
// для доступа к нестатическим членам они должны
// получить адрес объекта как параметр
static int Getnoboxes(CBox & C) {C.Set_l(0);return m_noboxes;}
};
// определение статической переменной обязательно вне класса
int CBox::m_noboxes=0;
// значение статической переменной в примере равно количеству объектов
// описанного класса
void main()
{
CBox mybox1; // 1 объект
mybox1.Print();
cout<<mybox1. Getnoboxes ()<<endl;
CBox mybox2(1,2); // 2 объект
mybox2.Print();
cout<<mybox1. Getnoboxes ()<<endl;
CBox mybox3(3,4,5); // 3 объект
mybox3.Print();
cout<<mybox1. Getnoboxes (mybox3)<<endl;
mybox3.Print();
}
ПРИМЕР 8. Массив объектов
Пример тот же. Создаем массив объектов данного класса.
#include <iostream.h>
class CBox // объявление класса
{
double m_length; // поле - длина
double m_width; // поле - ширина
double m_height; // поле - высота
static int m_noboxes; // поле - cтатическая переменная
public:
CBox() // конструктор
{m_length=0; m_width=0; m_height=0; m_noboxes++;}
CBox(double l,double w) // перегруженный конструктор
{m_length=l; m_width=w; m_height=0; m_noboxes++;}
CBox(double l, double w, double h) // перегруженный конструктор
{m_length=l; m_width=w; m_height=h; m_noboxes++;}
~CBox () // деструктор
{ cout << "destructor CBox done"<<endl;}
void Set_l(double l) { m_length=l;}
void Set_w(double w) { m_width=w;}
void Set_h(double h) { m_height=h;}
const double Get_l() { return m_length;}
const double Get_w() { return m_width;}
const double Get_h() { return m_height;}
const void Print ()
{cout <<" L="<<m_length<<" W="<<m_width<<" H="<<m_height
<< " m_noboxes = "<<m_noboxes<<endl; }
const double Volume( ) {return m_length*m_width*m_height;}
// cтатические функции-члены класса имеют доступ
// только к статическим членам класса.
static int Getnoboxes() {return m_noboxes;}
// для доступа к нестатическим членам они должны
// получить адрес объекта как параметр
static int Getnoboxes(CBox & C) {C.Set_l(0);return m_noboxes;}
};
// определение статической переменной обязательно вне класса
int CBox::m_noboxes=0;
// значение статической переменной в примере равно количеству объектов
// описанного класса
void main()
{
CBox mybox[4]; // массив объектов. конструктор по умолчанию!
cout<<"massiv1 "<<endl;
for(int i=0;i<4;i++)
{
cout<<i<<endl;
mybox[i].Print();
}
// другой массив объектов. инициализация
CBox mybox1[3];
mybox1[0]=СBox();
mybox1[1]=CBox(1,2);
mybox1[2]=CBox(3,4,5);
cout<<"massiv2 "<<endl;
for(i=0;i<3;i++)
{ cout<<i<<endl;
mybox1[i].Print();
}
// или так массив объектов. инициализация
CBox mybox2[3]={CBox(),CBox(1,2),CBox(3,4,5)};
cout<<"massiv3 "<<endl;
for(i=0;i<3;i++)
{ cout<<i<<endl;
mybox2[i].Print();
}
}
ПРИМЕР 9. Стандартный конструктор копирования
Использование стандартного конструктора копирования.
#include <iostream.h>
class CPoint
{ short m_a; // поле 1
short m_k; // поле 2
public:
CPoint() {m_a = 4; m_k = 1;} // конструктор
~CPoint() {} // деструктор
void Setk(short k) {m_k=k;} // инициализация поля 2
void Seta(short a) {m_a=a;} // инициализация поля 1
void Print () // вывод значений полей на экран
{cout << " a="<<m_a<<" k=" << m_k<<endl;}
};
int main()
{
CPoint x; // вызов конструктора – инициализация полей объекта х
x.Print(); // 4 1
CPoint y=x; // вызов стандартного конструктора копирования
y.Print(); // 4 1
x.Setk(5); // инициализация поля 2
x.Seta(8); // инициализация поля 1
x.Print(); // 8 5
y.Print(); // 4 1
return 0;
}
ПРИМЕР 10. Стандартный конструктор копирования не работает
Стандартный конструктор копирования нельзя использовать, если Вы работаете с членами – указателями.
#include <iostream.h>
class CPoint
{ short m_a; // поле 1
short *m_k; // поле 2 // изменим поле 2
public:
CPoint() {m_a=4; m_k=new short(1);} // конструктор
~CPoint() {} // деструктор
void Setk(short k) {*m_k=k;} // инициализация значения поля 2
void Seta(short a) {m_a=a;} // инициализация поля 1
void Print () // вывод значений полей на экран
{cout << " a="<<m_a<<" k=" << *m_k<<” “<<m_k<<endl;}
};
int main()
{
CPoint x; // вызов конструктора - инициализация полей
x.Print(); // 4 1
CPoint y=x; // вызов стандартного конструктора копирования
y.Print(); // 4 1
x.Setk(5); // инициализация значения поля 2
x.Seta(8); // инициализация поля 1
x.Print(); // 8 5
y.Print(); // 4 5 !!! но должно быть 4 1
return 0;
}
ПРИМЕР 11. Собственный конструктор копирования
Определение собственного конструктора копирования.
#include <iostream.h>
class CPoint
{ short m_a; // поле 1
short *m_k; // поле 2 // изменим поле 2
public:
CPoint() {m_a=4; m_k=new short(1);} // конструктор
CPoint ( CPoint &p) // собственный конструктор копирования
{m_a=p.m_a; m_k=new short(*p.m_k);}
~CPoint() {} // деструктор
void Setk(short k) {*m_k=k;} // инициализация значения поля 2
void Seta(short a) {m_a=a;} // инициализация поля 1
void Print () // вывод значений полей на экран
{cout << " a="<<m_a<<" k=" << *m_k<<” “<<m_k<<endl;}
};
int main()
{
CPoint x; // вызов конструктора - инициализация полей
x.Print(); // 4 1
CPoint y=x; // вызов собственного конструктора копирования
y.Print(); // 4 1
x.Setk(5); // инициализация значения поля 2
x.Seta(8); // инициализация поля 1
x.Print(); // 8 5
y.Print(); // 4 1
return 0;
}
ПРИМЕР 12. Вложенные классы
Пример объявление вложенного класса.
#include <iostream.h>
class Outer // объявление объемлющего класса
{
class Inner // объявление вложенного класса
{
int n;
public:
Inner(){ n=0;} // конструктор вложенного класса
int count(){return ++n;} // метод вложенного класса
};
Inner n;
public:
int count() {return n.count();} // метод объемлющего класса
};
int main()
{
Outer n;
cout<<n.count()<<endl; // 1!!!
// Inner m; // нельзя!!!
// cout<<m.count()<<endl;
// Outer:: Inner m; // нельзя!!!
// cout<<m.count()<<endl;
return 0;
}
ПРИМЕР 13. Вложенные классы
Пример объявление вложенного класса доступного вне объемлющего класса.
#include <iostream.h>
class Outer // объявление объемлющего класса
{
public:
class Inner // объявление вложенного класса
{
int n;
public:
Inner(){ n=0;} // конструктор вложенного класса
int count(){return ++n;} // метод вложенного класса
};
private:
Inner n;
public:
int count() {return n.count();} // метод объемлющего класса
};
int main()
{
Outer n;
cout<<n.count()<<endl; // 1!!!
//Inner m; // нельзя!!!
//cout<<m.count()<<endl;
Outer:: Inner m;
cout<<m.count()<<endl; // 1!!!
return 0;
}
ПРИМЕР 14. Шаблон классов
Шаблон классов для одномерного массива размерности Size.
#include <iostream.h>
template <class U=int, int Size=100> // шаблон классов
class MyArray // Объявление класса
{ U m_array [Size];
public:
MyArray(void) // конструктор
{for (int i=0; i<=Size-1; i++) m_array[i]=0;}
~MyArray(void) {} // деструктор
U Get (int i); // метод получения значения i элемента
void Put (int i, U x); // метод инициализации i элемента значением х
void Print() // метод вывода элементов массива на экран
{for (int i=0; i<Size; i++) cout << m_array[i] << " " ; cout<<endl;}
};
// Определения методов
template <class U, int Size> // шаблон метода
U MyArray < U, Size>::Get (int i)
{ if (i<0) i=0; if (i>Size-1) i=Size-1;
return m_array[i];}
template <class U, int Size> // шаблон метода
void MyArray < U, Size>::Put (int i, U x)
{ if (i<0) i=0; if (i>Size-1) i=Size-1;
m_array[i]=x;
}
int main()
{
MyArray <double, 5> darray; //объект - массив из 5 вещественных элементов
MyArray <> iarray; // объект - массив из 100 целых элементов
cout<<" darray = "<<endl; darray.Print();
cout<<" iarray = "<<endl; iarray.Print();
darray.Put(1,3.14);
iarray.Put(0,2);
darray.Put(0,iarray.Get(0));
cout<<" darray = "<<endl; darray.Print();
return 0;
}
ПРИМЕР 15. Перегрузка операторов
Пример шаблона классов CVecn, позволяющего работать с n-мерными векторами, заданными своими координатами в прямоугольной системе координат. Внутренне представление этого вектора – одномерный массив элементов типа double размером n элементов.
#include <iostream.h>
template <int Size=3>
class CVecn // объявление класса
{ double m_array[Size]; // массив – поле класса
public:
CVecn (void) {for (int i=0; i<Size; i++) m_array[i]=0;} // конструктор
~CVecn (void) {} // деструктор
CVecn operator - (); // унарный -
CVecn operator +=(const CVecn &r); // сложение векторов с замещением
CVecn operator +(const CVecn &r); // сложение векторов
CVecn operator -=(const CVecn &r); // вычитание векторов с замещением
CVecn operator -(const CVecn &r); // вычитание векторов
double operator *(const CVecn &r); // скалярное произведение
CVecn operator *(double l); // умножение вектора на скаляр
friend CVecn operator *(double l,CVecn &r) // умножение скаляра на вектор
{ return r*l;}
bool operator ==(const CVecn &r); // логическая операция равенства векторов
bool operator !=(const CVecn &r); // логическая операция неравенства векторов
double& operator [] (const int i); // оператор индексирования
// позволяет обращаться к элементам массива
// не нужны функции для доступа к полям (типа Set или Get).
};
template <int Size>
CVecn<Size> CVecn<Size>::operator -() // унарный -
{ CVecn <Size> Result;
for (int i=0; i<Size; i++)
Result.m_array[i] = -m_array[i];
return Result;
}
template <int Size>
double& CVecn <Size>::operator [](const int i)
// оператор индексирования
{ if (i<0) return m_array[0];
if (i>=Size) return m_array[Size-1];
return m_array[i];
}
template <int Size> // сложение векторов с замещением
CVecn <Size> CVecn <Size>::operator +=(const CVecn<Size> &r)
{ for (int i=0; i<Size; i++)
m_array[i] += r.m_array[i];
return *this;
}
template <int Size> // сложение векторов
CVecn <Size> CVecn <Size>::operator +(const CVecn<Size>& r)
{ CVecn <Size> Rezult;
for (int i=0; i<Size; i++)
Rezult.m_array[i] = r.m_array[i] + m_array[i];
return Rezult;
}
template <int Size> //вычитание векторов с замещением
CVecn <Size> CVecn <Size>::operator -=(const CVecn<Size> &r)
{ for (int i=0; i<Size; i++)
m_array[i] -= r.m_array[i];
return *this;
}
template <int Size> // вычитание векторов
CVecn <Size> CVecn <Size>::operator -(const CVecn<Size>& r)
{ CVecn <Size> Rezult;
for (int i=0; i<Size; i++)
Rezult.m_array[i] = r.m_array[i] - m_array[i];
return Rezult;
}
template <int Size> // скалярное произведение
double CVecn <Size>::operator *(const CVecn<Size>& r)
{ double sum = 0;
for (int i=0; i<Size; i++)
sum += m_array[i] * r.m_array[i];
return sum;
}
template <int Size> // умножение вектора на скаляр
CVecn <Size> CVecn <Size>::operator *(double r)
{ CVecn <Size> Result;
for (int i=0; i<Size; i++)
Result.m_array[i] = m_array[i]*r;
return Result;
}
template <int Size> // логическая операция равенства векторов
bool CVecn <Size>::operator ==(const CVecn<Size> &r)
{ for (int i=0; i<Size; i++)
if (m_array[i] != r.m_array[i]) return false;
return true;
}
template <int Size> // логическая операция неравенства векторов
bool CVecn <Size>::operator !=(const CVecn<Size> &r)
{
for (int i=0; i<Size; i++)
if (m_array[i] != r.m_array[i]) return true;
return false;
}
/*
template <int Size> // можно перегрузить оператор =
CVecn<Size>& CVecn <Size>::operator =(const CVecn <Size> &r )
{ if (&r !=this)
for (int i=0; i<Size; i++)
m_array[i] = r.m_array[i];
return *this;
}
*/
template <int Size> // внешняя функция
void Print(CVecn <Size> vect) // вывод элементов массива на экран
{
for (int i=0; i<Size; i++) cout << vect[i] << " " ; cout<<endl;
}
int main()
{ const SIZE=5;
// объявляем 3 объекта-вектора
CVecn <SIZE> vector1, vector2, vector3;
// инициализация 1 вектора
for (int i=0;i<SIZE;i++) vector1[i]=i;
cout<<" vector1= "<<endl; Print(vector1);
// унарный минус
cout<<" -vector1= "<<endl; Print(-vector1);
// инициализация 2 вектора
for (i=0;i<SIZE;i++) vector2[i] = i + 5;
cout<<endl<<" vector2= "<<endl; Print(vector2);
// сложение двух векторов с замещением
vector1 += vector2;
cout<<endl<<" vector1+=vector2 "<<endl; Print(vector1);
// сложение двух векторов
vector3 = vector1 + vector2;
cout<<endl<<" vector1+vector2= "<<endl; Print(vector3);
// умножение вектора на скаляр
vector1 = vector1 * 2;
cout<<endl<<" vector1*=2 "<<endl; Print(vector1);
// умножение скаляра на вектор
vector1=2*vector2;
cout<<endl<<" vector2*2= "<<endl; Print(vector1);
// сравнение на равенство векторов
cout<<endl<<"vector1==vector2= "<<(vector1==vector2)<<endl;
// скалярное произведение двух векторов
cout<<endl<<" scalarnoe= "<<(vector1*vector2)<<endl;
return 0;
}
ПРИМЕР 16. АТД - «комплексное число»
Создадим АТД для комплексных чисел.
// файл complex.h объявление класса
class CCmplx
{
double m_re; // действительная часть комплексного числа
double m_im; // мнимая часть комплексного числа
public:
CCmplx (double re=0, double im=0): m_re(re), m_im(im){} // конструктор
~CCmplx(void){} // деструктор
double & Re() {return m_re;} // действ. часть
double & Im() {return m_im;} // мнимая часть
double& operator [] (int i); // оператор []
CCmplx& operator () (double x=0, double y=0) // оператор ()
{m_re=x; m_im=y; return *this;}
CCmplx& operator = (CCmplx r); // оператор =
CCmplx& operator = (double r); // оператор =
CCmplx operator - (); // оператор - унарный
CCmplx operator + (); // оператор + унарный
CCmplx operator ++ (); // prefix
CCmplx operator ++ (int); //postfix
CCmplx operator +(CCmplx r); // + два комплексных числа
CCmplx operator - (CCmplx r); // - два комплексных числа
CCmplx CCmplx::operator *(CCmplx r); // * два комплексных числа
CCmplx CCmplx::operator /(CCmplx r); // / два комплексных числа
CCmplx operator + (double r); // комплексное число + вещественное
CCmplx operator - (double r); // комплексное число - вещественное
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.