Таким образом, мы не можем написать в классе два конструктора. Для решения этой проблемы надо написать две статические функции с разными именами, которые вызывают закрытый конструктор. Это могло бы выглядеть так, как показано в листинге 4.22.
Листинг 4.22. Именованные «конструкторы»
class Complex { public:
static Complex Decart(const double &re, const double &im); static Complex Polar (const double &r, const double &alpha); // остапьные члены класса private: double Re, Im;
Complex(const double &x, const double &y):Re(x), Im(y) {};
};
Complex Complex::Decart(const double &re, const double &im) { return Complex(re, im); }
Complex Complex::Polar (const double &r, const double &alpha) { return Complex(r*cos(alpha), r*sin(alpha)); }
Используются такие функции вполне традиционно:
const double pi = 3.1415926:
Complex a = Complex::Decart(1.0, 0.0):
Complex a = Complex::Polar (1.0, PI/2.0):
Это правильно работает именно потому, что статические функции могут быть вызваны до создания объекта, то есть до вызова конструктора — поэтому они этот конструктор и вызывают, создавая и возвращая объект.
Однако самое простое и, пожалуй, уже классическое применение статических полей — подсчет объектов. Для этого в классе объявляется статическое поле целого типа, которое увеличивается в конструкторе, а уменьшается в деструкторе. Это как раз тот случай, когда деструктор требуется определить явным образом, поскольку при уничтожении объекта нужно выполнять специфические действия. Таким способом можно собирать статистику интенсивности создания и уничтожения объектов некоторого класса (листинг 4.23).
Листинг 4.23. Подсчет объектов класса
#include <iostream> class Object
{ static unsigned int count; // статическое поле - счетчик
public:
ObjectO; // конструктор
~0bject(); // деструктор
static unsigned int CountO; // выдача счетчика
}:
unsigned int Object::count = 0; // определение и инициализация счетчика
Object::0bject() { ++count; } // увеличение счетчика при создании
Object::~0bject(){ --count; } // уменьшение счетчика при разрушении
unsigned int Object::Count() // получение значения
{ return count; } int main()
{ Object b; // объект только один
cout << мКоличество=" << Object::Count() << endl;
{ Object a[10]; // создается 10 объектов
cout << "Количество^' << Object::Count() << endl;
} // массив уничтожается
// объект опять только один cout << "Количество^' << Object::Count() << endl; return 0;
}
В классе Object задано статическое поле-счетчик, которое увеличивается в конструкторе, то есть при каждом создании объекта. При вызове деструктора счетчик уменьшается. Метод Count () сделан статическим, так как по своей сути этот метод является методом всего класса, а не отдельного объекта.
Программа демонстрирует изменения счетчика при «рождении» и «смерти» объектов — на экран выводится следующее:
Количеством // создание объекта b
Количество=11 // создание массива а[10]
Количеством // вышли из блока - массив уничтожен
Сначала создается только один объект Ь; при входе во внутренний блок создается массив а, в котором 10 объектов, и для каждого конструктор увеличивает счетчик. При выходе из блока элементы массива уничтожаются, и деструктор при каждом вызове уменьшает счетчик.
Если вы сделали для своей программы сайт на джумле, тогда вам необходим специальный хостинг, ведь она сильно грузит сервер - http://freehost.com.ua/faq/faq/professionalnij-internet-hosting-dlja-joomla-ot-freehost/.
Резюме
В качестве поля в классе может быть задан массив. Количество элементов массива должно определяться константным выражением, причем выражение должно быть определено до объявления поля-массива. Инициализировать поле-массив можно в теле конструктора. Инициализация массива с помощью списка инициализации конструктора ограничена: разрешается только инициализация нулем. Константный массив встроенного типа невозможно инициализировать никаким способом. При инициализации константного массива невстроенного типа для каждого элемента массива вызывается конструктор по умолчанию.
Обычно при наличии в классе полей-массивов перегружается операция индексирования operator [], которая возвращает ссылку на объект того же класса. Операция перегружается в двух вариантах: как константная и неконстантная.
Класс может содержать статические элементы: поля и методы, которые являются элементами класса, а не объекта. Статические поля в классе только объявляются, их требуется еще отдельно определить вне класса. При определении статические поля могут быть проинициализированы. Если явной инициализации нет, то статические поля класса по умолчанию инициализируются нулями, как и глобальные переменные. Статические поля не занимают место в классе. Статические методы не получают указателя thi s в качестве параметра, они не могут быть ни константными, ни виртуальными. |