Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4152

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Глава 14. Классы 

191 

Статические  данные-члены  класса  только  объявляются  внутри 

класса.  Они  должны  быть  определены,  а  в  случае  констант  и 

инициализированы  вне  класса.  Пример  работы  со  статическими 

данными-членами класса приведен в листинге 14.10. 

Листинг 14.10. Работа со статическими данными-членами класса 

#include <iostream> 
using namespace std; 
 
struct Demo 

  static int n; 
  static const int m; 
}; 
int Demo::n; 
const int Demo::m = 10; 
 
int main() 

  Demo::n = 20; 
  cout << Demo::n << ' ' << Demo::m << endl;  // 20 10 
 
  return 0; 

Можно определять указатели на статические данные-члены клас-
са, если они расположены в разделе 

public

. Например: 

  int* p = &Demo::n; 

Статические  функции-члены  класса  имеют  доступ  только  к  ста-

тическим  данным-членам  класса.  Для  того  чтобы  эти  функции 

имели  доступ  к  нестатическим  членам  класса,  они  должны  

получить  адрес  объекта  класса  как  параметр.  Пример  работы  

со  статическими  функциями-членами  класса  приведен  в 

листинге 14.11. 

Листинг 14.11. Работа со статическими функциями-членами класса 

#include <iostream> 
using namespace std; 


background image

Часть II. Язык программирования С++ 

192 

class Demo 

  int n; 
  static int m; 
public: 
  Demo() { n = 10; ++m; } 
  static int getN(Demo& d) { return d.n; } 
  static int getM() { return m; } 
  int getSum() { return n + m; } 
}; 
int Demo::m; 
int main() 

  Demo d; 

 

  cout << d.getN(d) << endl;   // 10 
  cout << d.getM() << endl;    // 1 
  cout << d.getSum() << endl;  // 11 

 

  return 0; 

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

  int (*f)(void) = Demo::getM; 

14.11. Указатели  

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

При определении указателей на нестатические члены класса сле-
дует учитывать как тип члена класса, так и тип самого класса. 
Определение  указателя  на  нестатический  атрибут  класса  имеет 
следующий вид: 

  тип_атрибута имя_класса::*  имя_указателя 

В  свою  очередь  определение  указателя  на  нестатический  метод 
класса имеет следующий вид: 

  тип (имя_класса::* имя_указателя)(список_параметров) 


background image

Глава 14. Классы 

193 

Для  доступа  к  нестатическим  членам класса  через  указатели  ис-
пользуются операторы: 

 

.*

 — для объектов или ссылок на объекты; 

 

->*

 — для указателей на объекты. 

Эти операторы имеют ассоциативность слева направо, а их при-
оритет ниже приоритета унарных арифметических операторов, но 
выше приоритета бинарных арифметических операторов. 
В  листинге  14.12  приведен  пример  использования  операторов 
доступа к нестатическим членам класса через указатели. 

Листинг 14.12. Доступ к нестатическим членам класса  
через указатели 

#include <iostream> 
using namespace std; 
struct Demo 

  int n; 
  int Count() { return n; }; 
}; 
int main() 

  Demo d; 
  Demo* dp = &d; 

 

  int Demo::*ip;      // указатель на атрибут 
  int (Demo::*fp)();  // указатель на метод 

 

  // инициализация указателей 
  ip = &Demo::n; 
  fp = Demo::Count; 

 

  // доступ к атрибуту через объект 
  d.*ip = 10; 
  cout << d.*ip << endl;    // печатает 10 

 

  // доступ к атрибуту через указатель на объект 
  dp->*ip = 20; 
  cout << dp->*ip << endl;  // печатает 20 


background image

Часть II. Язык программирования С++ 

194 

  d.*ip += 10; 
  // доступ к методу через объект 
  cout << (d.*fp)() << endl;    // печатает 30 
  // доступ к методу через указатель на объект 
  cout << (dp->*fp)() << endl;  // печатает 30 
 
  return 0; 

14.12. Вложенные классы 

Класс,  объявленный  внутри  другого  класса,  называется 

вло-

женным 

классом.  Класс,  в  котором  объявлен  вложенный  класс, 

будем называть 

объемлющим

 классом. 

Функции-члены  объемлющего  класса  не  имеют  прав  доступа  к 
закрытым  членам  своего  вложенного  класса.  Также  и  функции-
члены  вложенного  класса  не  имеют  прав  доступа  к  закрытым 
членам класса, внутри которого он объявлен. Чтобы предоставить 
такие  права  вложенному  или  объемлющему  классу,  нужно  объ- 
явить такой класс другом соответственно объемлющего или вло-
женного класса. 
В  листинге  14.13  приведен  пример  объявления  вложенного  
класса. 

Листинг 14.13. Пример объявления вложенного класса 

#include <iostream> 
using namespace std; 
class Outer 

  class Inner 
  { 
    int n; 
  public: 
    Inner() { n = 0; } 
    int count() { return ++n; } 
  }; 
  Inner n; 


background image

Глава 14. Классы 

195 

public: 
  int count() { return n.count(); } 
}; 
int main() 

  Outer n; 
  cout << n.count() << endl;  // печатает 1 
 
  return 0; 

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

Листинг 14.14. Объявление объекта типа вложенного класса 

#include <iostream> 
using namespace std; 
 
class Outer 

public: 
  class Inner 
  { 
    int n; 
  public: 
    Inner() { n = 0; } 
    int count() { return ++n; } 
  }; 
private: 
  Inner n; 


Смотрите также файлы