Статические поля класса.
Статическое поле данных класса принадлежит всем объектам данного класса и существует в единственном экземпляре. При создании объектов класса статические поля не тиражируются, в отличие от остальных данных-членов класса. Следует отметить, что доступ к статическому полю возможен только после инициализации (выделения памяти и задания начального значения). Инициализировать статическую переменную нужно вне класса в глобальной области данных для того, чтобы экземпляры класса, создаваемые после этого имели к ней доступ.
Добавим в класс MyStr три поля :
статическое открытое поле num – порядковый номер строк
статическое закрытое поле count – общее количество существующих строк
нестатическое открытое поле nn – для хранения порядкового номера строки
Добавим метод:
get_count() – для внешнего чтения закрытого поля count
Нам придется видоизменить конструктор и метод display(), так как им придется работать с новыми полями, также добавим в класс деструктор.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
class MyStr
{ static int count; // счетчик существующих строк
char *buf; // закрытые данные
public:
static int num; // счетчик порядкового номера
int nn; // порядковый номер строки
// конструктор (инициализация параметром)
MyStr(const char *str)
{ cout<< "Выполняется конструктор! ";
num++; // при создании объекта счетчики наращиваются
count++;
nn=num;
buf= new char[strlen(str)+1]; // выделение динамической памяти
strcpy(buf, str);// копирование строки-параметра в выделенную память
}
// деструктор
~MyStr()
{ cout<< "Выполняется деструктор!";
count--; // строка уничтожена, счетчик уменьшается
}
void display()
{ cout<<nn<<':'<<buf<<endl;
cout<<"count="<<count<<endl;
cout<<"nn="<<nn<<endl;
}
char* get_mystr ()
{ return buf;
}
int get_count ()
{ return count;
}
};
/* инициализация статических переменных в глобальной области данных
(вне функции main)*/
int MyStr::count=0;
int MyStr::num=0;
// внешняя (по отношению к классу MyStr MyStr) часть программы
int main(int argc, char* argv[])
{// создание первой строки (экземпляр класса MyStr)
MyStr c1("first");
c1.display();
cout<<"Внешняя работа с переменными :";
cout<<" count =";
cout<<c1.get_count(); // работа с закрытой статической переменной
cout<<"\t num="; // работа с открытой стат. переменной (1-ый способ)
cout<<MyStr::num;
cout<<"\t nn="<<c1.nn<<endl; // работа с открытой нестат. переменной
// создание второй строки (экземпляр класса MyStr)
MyStr c2("second");
c2.display();
cout<<"Внешняя работа с переменными :";
cout<<"num="; // работа с открытой статической переменной (2-ой способ)
cout<<c1.num<<endl;
{ cout<<endl<<endl<<"Начало вложенного блока"<<endl;
// создание третьей строки (локальный объект блока)
MyStr c3("third");
c3.display();
cout<<endl<<endl<<"Конец вложенного блока(end)"<<endl;
} // уничтожение локальных объектов при выходе из блока
MyStr c4("fourth"); // создание четвертой строки
c4.display();
system ("pause");
return 0;
}
Обратите внимание, что статическая переменная count определена в закрытой части класса, в этом случае в вызывающей программе обратиться к ней можно только с помощью метода класса get_count (внешнее обращение). Статические переменные (как открытые, так и закрытые) существуют в единственном экземпляре, создаются при инициализации и принадлежат всем объектам класса. Поэтому и инициализировать обращение к ним может любой из объектов класса (с1,с2,с3,с4) – результат будет один и тот же. В нашем примере метод get_count() всегда вызывается объектом с1.
Статическая переменная num определена как открытая, поэтому из вызывающей программы к ней есть непосредственный доступ: MyStr::num (с уточнением принадлежности к классу) или с1.num (через любой из объектов класса).
Нестатическая переменная nn имеется в каждом объекте класса и определена как открытая (в public-области класса MyStr), поэтому в вызывающей программе обращаться к ней следует через соответствующий объект класса, используя уточненное имя, например: c1.nn, c2.nn и т.п.
Поговорим о конструкторах и деструкторах. Конструкторы всегда вызываются явно при создании объектов класса, например: MyStr c1("first"). Деструкторы чаще вызываются неявно, при уничтожении объекта класса. В нашем примере уничтожается объект с3 при выходе из вложенного блока.
