//Point2d.Cpp
ostreamf operator<<(ostream& out, Poind2D p)
{
return out<<”Точка: ”
<<p.x<<” “
<<p.y;
}
istream operator >>(istream &in, Point2D&)
{
cout<<”Точка ”;
return in >>p.x>>p.y;
}
Point2D p2, const Point2D p1(1,2);
cin>>p2;
cout<<p1+p2<<”\n”
<<p1*p2<<”\n”;
cout<<p1+2<<2+p1<<”\n”<<p.y;
Аналогичным образом можно объявить дружественные для класса обычным глобальным функциям, член-функциям другого класса и даже сделать все член-функции одного класса дружественными другому классу.
class B;
class C;
class A
{
int m1;
char m2;
friend void ff(A);//глобальная функция ff дружественная классу А
public
char fm(c);
char fm2(b,c);
};
class B
{
double mb2;
friend char A::fm2(B,C);//функция класса А, дружественная классу В
...
}
class C
{
char mc1;
friend class A;//все член-функции класса А дружественные классу С
...
}
При введении дружественных функций, надо быть осторожным, т.к. использование дружественных функций нарушает принцип сокрытия информации или принцип инкапсуляции. Как правило дружественные функции используются для перегрузки операций и для создания класса операндов.
Подробное изучение класса
Определение класса в области видимости
Класс – это тип данных, определенный пользователем и представляющий набор данных и множество операций для работы с этими данными. При объявлении используются общие правила объявления.
В языке в С++ поддерживается 2 области видимости: область видимости файла, локальная область видимости, область видимости класса. Объявленные в области видимости файла видны до конца файла. Локальная область видимости – в ней видны только в этом блоке. Локальное объявление перекрывает глобальное. Член-данные и методы класса видны только в видимости класса. Вне его требуется уточнение имени объекта или класса.
Для ограничения доступа используется 3 спецификатора: public, private и protected. Член класса виден и может быть использован во всем классе независимо от точки объявления, а в определении класса и до своего определения.
int var;
class Ex
{
public:
f(){var =0};
private:
int var;//речь будет идти об этой переменной
}
Член функция класса имеет область видимости класса и определяет собственную локальную область видимости аналогично обычной функции С.
class Point2D
{
double x,y;
public:
Point2D(double x, double y)
{
Point2D::x=x;
Point2D::y=y;
}
}
Опережающее объявление класса
exteen int count;
struct POINT;
class Point2D;
Использование опережающих объявлений класса возможно только при объявлении ссылок и указателей, т.е. в тех случаях, когда не важна внутренняя структура класса.
Типы памяти
Статические объекты создаются и инициализируются в статическом сегменте данных и остается там не меняя своего положения до конца программы.
К автоматическому классу памяти относятся переменные, типы класса. Автоматические объекты создаются в стеке и завершают свое существование при выходе из программы.
Динамические создаются, инициализируются и уничтожаются по требованию программиста. Они создаются в С++ при помощи new и delete.
Иногда возникает необходимость, чтобы все объекты имели доступ к какой-то одной общей переменной, а не копии переменной в каждом объекте. Эта переменная например может быть счетчиком, флажком и другое. Для того, чтобы элемент данного класса разделял всеми объектами данного класса и находилось в фиксированном месте в памяти, его нужно объявить с ключевым словом static.
class Point2D
{
double x,y;
static int count;
public:
Point2D(double x, double y)
{
x=_x;
y=_y;
count++;
}
~Point2D()
{
count--;
}
};
//point2d.cpp
int Point2D::count;
Объявление статической переменной не является его определением. Поэтому в каком-либо из модулей надо определить его и если надо провести инициализацию. При этом надо использоваться полное имя данных.
//получение доступа к объекту
cout<<Point2D::Count<<”\n”;
Для открытия доступа к открытому или защищенному типу, должна быть предусмотрена открытая статическая член-функция, которая должна вызываться с добавлением перед ее именем имени класса.
static int GetCount()
{
return count;
}
cout<<Point2D::GetCount();
Так как статические данные находятся вне любого объекта. то статические данные не получают указателя this в качестве параметра и поэтому может работать со статическими данными класса.
Замечания: в создании и инициализации статических данных происходит при запуске программы в порядке поступления их определений на вход компоновщика. Однако не следует проектировать программу так, чтобы их работа зависела от порядка создания и инициализации статических данных.
