- •Классы и заголовочные файлы Отделение объявления от реализации
- •Int m_month;
- •Int m_year;
- •Int getValue () { return m_value ; }
- •Int getValue () {return m_value;}
- •Классы и заголовочные файлы
- •Int getDay () {return m_day;}
- •Void Date::SetDate (int day, int month, int year) {
- •Параметры по умолчанию
- •Библиотеки
- •Заключение
- •Классы и const
- •Константные объекты классов
- •Int m_value;
- •Int getValue () { return m_value ; }
- •Int main () {
- •Константные методы классов
- •Int m_value;
- •Int m_value;
- •Int m_value;
- •Константные ссылки и классы
- •Int getDay () {return m_day;}
- •Void printDate (const Date &date) {
- •Int main () {
- •Int m_month;
- •Int m_year;
- •Void setDate (int day, int month, int year) {
- •Перегрузка константных и неконстантных функций
- •Int main () {
- •Статические переменные-члены класса
- •Статические переменные-члены класса
- •Int generateId () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Статические члены не связаны с объектами класса
- •Int main () {
- •Определение и инициализация статических переменных-членов класса
- •Инициализация статических переменных-членов внутри тела класса
- •Использование статических переменных-членов класса
- •Int getId() const { return m_id; }
- •Int main () {
- •Статические методы класса
- •Int main () {
- •Int main () {
- •Статические методы не имеют указателя this
- •Int main () {
- •Предупреждение о классах со всеми статическими членами
- •Int main () {
- •Дружественные функции и классы
- •Int m_value;
- •Void reset (Anything &anything) {
- •Int main () {
- •Int m_value;
- •Дружественные функции и несколько классов
- •Дружественные классы
- •Примечания о дружественных классах:
- •Дружественные методы
- •If (m_displayIntFirst)
- •Int m_intValue;
- •Values (int intValue, double dValue) {
- •Анонимные объекты
- •Int main () {
- •Анонимные объекты класса
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars() const { return m_dollars; }
- •Int main () {
- •Вложенные типы данных в классах
- •Int main () {
- •Вложенные пользовательские типы данных в классах
- •Int main () {
- •Другие вложенные пользовательские типы данных в классах
Вложенные пользовательские типы данных в классах
В отличие от функций, которые не могут быть вложены (находится внутри друг друга), в языке C++ пользовательские типы данных могут быть определены (вложены) внутри класса. Для этого нужно просто определить пользовательский тип внутри класса под соответствующим спецификатором доступа.
Вот вышеприведенная программа, но уже с FruitList, определенным внутри класса:
#include <iostream>
class Fruit {
public:
// Мы переместили FruitList внутрь класса под спецификатором //доступа public
enum FruitList {
AVOCADO,
BLACKBERRY,
LEMON
};
private:
FruitList m_type;
public:
Fruit (FruitList type): m_type(type) {}
FruitList getType () {return m_type;}
};
Int main () {
// Доступ к FruitList осуществляется через Fruit
Fruit avocado (Fruit::AVOCADO);
if (avocado.getType () == Fruit::AVOCADO)
std::cout << "I am an avocado!";
else
std::cout << "I am not an avocado!";
return 0;
}
Обратите внимание:
Во-первых, FruitList теперь определен внутри тела класса.
Во-вторых, мы определили его под спецификатором доступа public, т.е. сделали доступ к FruitList открытым.
По сути, классы работают как пространства имен для любых вложенных типов.
В первом примере мы имеем доступ к перечислителю AVOCADO напрямую, так как AVOCADO определен в глобальной области видимости (мы могли бы предотвратить это, используя класс enum вместо обычного enum, и тогда доступ к AVOCADO осуществлялся бы через FruitList::AVOCADO).
Теперь, поскольку FruitList считается частью класса, доступ к перечислителю AVOCADO осуществляется через имя класса, например: Fruit::AVOCADO.
Обратите внимание, поскольку классы enum также работают как пространства имен, и если бы мы поместили класс enum (вместо обычного enum) с именем FruitList внутрь класса Fruit, то доступ к перечислителю AVOCADO осуществлялся бы через Fruit::FruitList::AVOCADO.
Другие вложенные пользовательские типы данных в классах
Хотя перечисления являются наиболее распространенным вложенным пользовательским типом данных внутри классов, язык C++ также позволяет определять и другие пользовательские типы внутри классов, такие как псевдонимы типов (typedef и type alias) и даже другие классы!
=====================
в C++11 ввели улучшенный синтаксис для typedef, который имитирует способ объявления переменных.
Этот синтаксис называется type alias.
С помощью type alias мы пишем имя, которое затем используется как синоним конкретного типа данных (т.е. принцип тот же, но синтаксис более удобен).
Следующий typedef:
typedef double time_t; // используем time_t в качестве псевдонима //для типа double
В С++11 можно объявить, как:
using time_t = double; // используем time_t в качестве //псевдонима для типа double
Эти два способа функционально эквивалентны.
Обратите внимание, что хоть мы и используем ключевое слово using, оно не имеет ничего общего с using-директивами. Это ключевое слово имеет различный функционал в зависимости от контекста.
Новый синтаксис создания псевдонимов создает меньше проблем при использовании в сложных ситуациях, и его рекомендуется применять вместо обычного typedef.
Правило: Используйте type alias вместо typedef.
=============================
Как и любой обычный член класса, вложенный класс будет иметь доступ ко всем членам класса-оболочки (в котором он размещен). Однако вложенные классы не имеют доступа к указателю this класса-оболочки.
Определение вложенных типов не очень распространено, но Стандартная библиотека C++ все же использует это в некоторых случаях.
