русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Перегрузка конструкторов


Дата добавления: 2013-12-23; просмотров: 1126; Нарушение авторских прав


Глава 4. Перегрузка функций и операторов

Статические члены класса

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

При объявлении статического члена данных класса этот член не определяется, а просто резервируется место в классе. Затем необходимо определить статические члены класса глобально вне класса. Это делается путем нового объявления статической переменной, причем используется оператор области видимости для того, чтобы идентифицировать тот класс, к которому принадлежит переменная. Это необходимо для того, чтобы под статическую переменную была выделена память.

В качестве примера рассмотрим следующую программу:

#include <iostream.h>

class counter

{

static int count;

public:

void setcount(int i) { count = i; }

void showcount() { cout << count << " ";}

};

int counter::count; // определение count

int main()

{

counter a, b;

a.showcount(); // выводит 0

b.showcount(); // выводит 0

a.setcount(10); // установка статического count в 10

a.showcount(); // выводит 10

b.showcount(); // также выводит 10

return 0;

}

В первую очередь обратим внимание на то, что статическая переменная целого типа count объяв­ляется в двух местах: в классе counter и затем — как глобальная переменная. Компилятор иници­ализирует count нулем. Именно поэтому первый вызов showcount() выводит в качестве результата нуль. Затем объект а устанавливает count равным 10. После этого оба объекта а и b выводят с помощью функции showcount() одну и ту же величину, равную 10. Поскольку существует только одна копия count, используемая совместно объектами а и b, то на экран выводится в обоих слу­чаях значение 10.



ПАМЯТКА: Когда член класса объявляется статическим, тем самым определя­ется, что будет создаваться только одна копия этого члена, которая будет затем совместно использоваться всеми объектами этого класса.

Также можно иметь статические функции-члены. Статические функции-члены не могут прямо ссылаться на нестатические данные или нестатические функции, объявленные в их классе. Причи­ной тому является отсутствие для них указателя this, так что нет способа узнать, с какими именно нестатическими данными работать. Например, если имеется два объекта класса, содержащие стати­ческую функцию f(), и если f() пытается получить доступ к нестатической переменной var, опреде­ленной этим классом, то как можно определить, какую именно копию var следует использовать? Компилятор не может решить такую проблему. В этом заключается причина того, что статичес­кие функции могут обращаться только к другим статическим функциям или статическим данным. Также статические функции не могут быть виртуальными или объявляться с модификаторами const или volatile. Статическая функция может вызываться либо с использованием объекта класса, либо с использованием имени класса и оператора области видимости. Тем не менее, не надо забы­вать, что даже при вызове статической функции с использованием объекта, ей не передается указатель this.

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

#include <iostream.h>

enum access_t { shared, in_use, locked, unlocked };

class access

{

static enum access_t acs;
// . . .
public:

static void set_access(enum access_t a) { acs = a; }

static enum access_t get_access() { return acs; }

};

enum access_t access::acs; // определение acs

int main()

{

access obj1, obj2;

access::set_access(locked); // вызов с использованием имени класса

// ... код

// может ли obj2 обращаться к ресурсу

if(obj2.get_access()==unlocked)

{

access::set_access(in_use); // вызов с помощью имени класса

cout << "Access resource.\n";

}

else cout << "Locked.\n";

return 0;

}

При запуске этой программы на экране появится «Locked». Обратим внимание, что функция set_access() вызвана с именем класса и оператором области видимости. Функция get_access() вы­звана с объектом и оператором «точка». При вызове статической функции может использовать­ся любая из этих форм и обе они дают одинаковый эффект.

Как отмечалось, статические функции имеют прямой доступ только к другим статическим фун­кциям или статическим данным в пределах одного и того же класса. В приведенном выше примере статические функции set_access() и get_access() работают только со статической переменной acs.

 

В прошлой главе кратко обсуждалась перегрузка функций и операторов, являющаяся важнейшей особенностью языка C++. В этой главе мы подробно рассмотрим вопросы, связанные с перегрузкой. Также в ходе этого обсуждения будут затронуты и смежные вопросы.

Хотя конструкторы и предназначены для решения особо важных задач, они мало отличаются от обычных функций и могут быть перегружены. Как было показано в примере пункта 3.11, для перегрузки конструктора класса достаточно просто объявить различные его формы. Как будет показано далее, во многих случаях перегрузка конструкторов позволяет до­биться определенных преимуществ.

Начнем с примера. В следующей программе объявляется класс timer, действующий как таймер обратного отсчета. При создании объекта типа timer ему присваивается начальное значение вре­мени. В результате вызова функции run() таймер начинает отсчет в сторону уменьшающихся зна­чений, пока не достигнет значения 0. В данном примере конструк­тор перегружен для того, чтобы можно было указывать время в секундах с помощью целого числа или строки, или в минутах и секундах, если указываются два целых числа.

Эта программа использует библиотечную функцию clock(), возвращающую число тиков, про­шедших с момента запуска программы. Поделив это значение на макрос CLOCKS_PER_SEC, получаем значение в секундах. Прототип clock() и макрос CLOCKS_PER_SEC содержатся в заголовочном файле time.h.

#include <iostream.h>

#include <stdlib.h>

#include <time.h>

class timer

{

int seconds;

public:

timer(char *t) { seconds = atoi(t); }

timer(int t) { seconds = t; }

timer(int min, int sec) { seconds = min*60 + sec; }

void run();

};

void timer::run()

{

clock_t t1, t2;

t1 = t2 = clock()/CLOCKS_PER_SEC;

while(seconds)

{

if(t1+1 <= (t2=(clock()/CLOCKS_PER_SEC)))

{

seconds--; t1 = t2;

}

}

cout << "\a"; // звонок

}

int main()

{

timer a(10), b("20"), c(1, 10);

a.run(); // отсчитать 10 секунд

b.run(); // отсчитать 20 секунд

с.run(); // отсчитать 1 минуту 10 секунд

return 0;

}

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



<== предыдущая лекция | следующая лекция ==>
Указатели на объекты | Локализация создания объектов


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.006 сек.