Студопедия — Статические поля класса.
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Статические поля класса.






Итак, поле класса можно объявить со служебным словом static. Память под такие поля резервируется при запуске программы, то есть еще до того, как программист явно создаст первый объект данного абстрактного типа.При этом все объекты, сколько бы их ни было, используют эту заранее созданную одну - единственную копию своего статического члена.

Статический член класса должен быть инициализирован после определения класса и до первого описания объекта этого класса. Данное действие производится с помощью так называемого полного или квалифицированного имени статического члена, которое имеет вид:

  имя_класса::имя_статического_члена

Рассмотрим пример. Реализуем класс object_, в статическом члене которого хранится число существующих в каждый момент времени объектов типа object_.

# include <iostream> # include <string.h> using namespace std;   class object_{ char *str; public: //статическое поле класса static int num_obj;   //конструктор object_ (char *s){ str = new char [strlen (s) + 1]; strcpy (str, s); cout <<"Create " << str <<'\n';   // увеличиваем значение счетчика num_obj ++; }   //деструктор ~object_ (){ cout <<"Destroy " << str << '\n'; delete str;   // уменьшаем значение счетчика num_obj --; } };   // Инициализация. Об этом говорит // ключевое слово int! int object_::num_obj = 0;   // создание глобальных объектов object_ s1 ("First global object."); object_ s2 ("Second global object.");   // вспомогательная функция void f (char *str) { // Локальный объект object_ s(str); // явное обращение к статическому полю // без указания объекта cout <<"Count of objects - " <<object_::num_obj<<".\n"; cout <<"Worked function f()" <<".\n"; }   void main () { // явное обращение к статическому полю cout <<"Now, count of objects " <<object_::num_obj<<".\n"; object_ M ("Object in main ().");   // обращение к статическому полю через объект cout <<"Now, count of objects" << M.num_obj <<".\n";   f ("Local object."); f ("Another local object.");   cout << "Before finish main() count of objects - " <<object_::num_obj<<".\n"; }   Результаты работы программы:   Create First global object. Create Second global object. Now, count of objects 2. Create Object in main (). Now, count of objects3. Create Local object. Count of objects - 4. Worked function f(). Destroy Local object. Create Another local object. Count of objects - 4. Worked function f(). Destroy Another local object. Before finish main() count of objects - 3. Destroy Object in main (). Destroy Second global object. Destroy First global object.

Примечание:Обратим внимание, что конструкторы для глобальных объектов вызываются до функции main (), а деструкторы после main().

На статические данные класса распространяются правила статуса доступа. Если статические данные имеют статус private, то к ним извне можно обращаться через компонентные функции. Другими словами, получается, что, если к моменту необходимости обращения к статическому полю типа private, объект класса еще не определен, обрашение невозможно. Согласитесь, хотелось бы иметь возможность обойтись без имени конкретного объекта при обращении к статическим данным класса. Эта задача решается с помощью статической компонентной функции-метода.

Статические методы класса.

Перед объявлением функции-члена класса можно поставить служебное слово static и она становится - статической компонентной функцией. Такая функция сохраняет все основные особенности обычных (нестатических) функций класса. К ней можно обращаться, используя имя уже существующего объекта класса либо указатель на такой объект.

Кроме того, статическую компонентную функцию можно вызвать следующим образом:

имя_класса::имя_статической_функции

Статические функции-члены позволяют получить доступ к приватным статическим данным-членам класса, не имея еще ни одного объекта данного типа в программе.

Но, внимание!!!

Для статической компонентной функции не определен указатель this. Когда это необходимо, адрес объекта, для которого вызывается статическая функция-член, должен быть передан ей явно в виде аргумента.

Рассмотрим пример:

  # include <iostream> using namespace std;   class prim{   int numb; // статическое поле static stat_;   public: prim (int i) { numb=i; }   /* Статическая функция. Указатель this не определен, поэтому выбор объекта осуществляется по явно переданному указателю. Поле stat_ не требует указателя на объект,т.к. оно общий для всех объектов класса prim. */ static void func (int i, prim *p = 0) { // если хотя бы один объект есть if(p) p->numb = i; // если объектов класса нет else stat_ = i; }   /* Статическая функция обращается только к статическому члену класса, никаких указателей не требуется. */ static void show(){ cout<<"stat_="<<stat_<<"\n\n"; }   //показ нестатического члена void show2(){ cout<<"numb="<<numb<<"\n\n"; } };   // Инициализация статического члена класса. int prim::stat_ = 8;   void main(){   /* До создания объектов типа prim возможен единственный способ обращения к статической функции-члену. */ prim::show ();   // Можно изменить значение статического члена класса. prim::func(10);   /* После создания объекта типа prim можно обратиться к статической функции обычным для абстрактных типов способом. */   // Создается объект obj и его поле numb // становится равным 23. prim obj(23); obj.show2();   // Можно изменить значение созданного объекта. prim::func(20, &obj); // obj.numb 20. obj.show2();   obj.func(27, &obj); // obj.numb 27. obj.show2(); }

Шаблон Синглетон (Singleton pattern)

Одним из применений статических членов является конструкция под названием Singleton pattern. Данная конструкция позволяет создавать только один экземпляр класса, и обеспечивает глобальный доступ к этому экземпляру.

Иногда бывает очень важно, чтобы класс мог создать только один экземпляр (объект). Например, система может иметь несколько принтеров, но должен быть только один спулер принтера. Как мы можем гарантировать, что имеется только один экземпляр класса, и что этот экземпляр доступен?! Можно, например, объявить глобальную переменную. Однако, данный способ плох тем, что мы во-первых засоряем пространство имен, а во-вторых не можем предотвратить создание нескольких экземпляров класса.

Лучшим решением будет класс, который сам отслеживает создание экземпляров и доступ к единственному объекту. Мы можем сделать так, чтобы класс гарантировал, что никакой другой экземпляр не может быть создан.

Надо написать класс, у которого можно создать только один экземпляр, но этим экземпляром должны пользоваться объекты других классов. Вот, пожалуй, самая простая из схем, реализующих эту задачу.

# include <iostream> using namespace std;   class Singleton{   private:   // указатель на единственный экземпляр класса static Singleton*s; int k;   //закрытый конструктор Singleton(int i){ k = i; }   public: //функция для получения указателя на //единственный экземпляр класса static Singleton*getReference(){ return s; }   //получение значения нестатического члена класса int getValue(){ return k; }   //перезапись значения нестатического члена класса void setValue(int i){ k = i; } };   // Инициализация статического члена класса. Singleton* Singleton::s=new Singleton(3);   void main(){   //получение указателя на //единственный экземпляр класса Singleton*p=Singleton::getReference();   //работа с компонентом объекта cout<<p->getValue()<<"\n\n"; p->setValue(p->getValue()+5); cout<<p->getValue()<<"\n\n"; }






Дата добавления: 2015-10-01; просмотров: 461. Нарушение авторских прав; Мы поможем в написании вашей работы!



Вычисление основной дактилоскопической формулы Вычислением основной дактоформулы обычно занимается следователь. Для этого все десять пальцев разбиваются на пять пар...

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Вопрос. Отличие деятельности человека от поведения животных главные отличия деятельности человека от активности животных сводятся к следующему: 1...

Расчет концентрации титрованных растворов с помощью поправочного коэффициента При выполнении серийных анализов ГОСТ или ведомственная инструкция обычно предусматривают применение раствора заданной концентрации или заданного титра...

Психолого-педагогическая характеристика студенческой группы   Характеристика группы составляется по 407 группе очного отделения зооинженерного факультета, бакалавриата по направлению «Биология» РГАУ-МСХА имени К...

СИНТАКСИЧЕСКАЯ РАБОТА В СИСТЕМЕ РАЗВИТИЯ РЕЧИ УЧАЩИХСЯ В языке различаются уровни — уровень слова (лексический), уровень словосочетания и предложения (синтаксический) и уровень Словосочетание в этом смысле может рассматриваться как переходное звено от лексического уровня к синтаксическому...

Плейотропное действие генов. Примеры. Плейотропное действие генов - это зависимость нескольких признаков от одного гена, то есть множественное действие одного гена...

Методика обучения письму и письменной речи на иностранном языке в средней школе. Различают письмо и письменную речь. Письмо – объект овладения графической и орфографической системами иностранного языка для фиксации языкового и речевого материала...

Studopedia.info - Студопедия - 2014-2024 год . (0.035 сек.) русская версия | украинская версия