- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
Как уже упоминалось, у класса будут также две функции-члена, combine() и isbn(). Кроме того, предоставим классу Sales_data другую функцию-член, чтобы возвращать среднюю цену, по которой были проданы книги. Эта функция, назовем ее avg_price(), не предназначена для общего использования. Она будет частью реализации, а не интерфейса.
Функции-члены определяют (см. раздел 6.1) и объявляют (см. раздел 6.1.2) как обычные функции. Функции-члены должны быть объявлены в классе, но определены они могут быть непосредственно в классе или вне тела класса. Функции, не являющиеся членами класса, но являющиеся частью интерфейса, как функции add(), read() и print(), объявляются и определяются вне класса.
С учетом вышеизложенного напишем пересмотренную версию класса Sales_data:
struct Sales_data {
// новые члены: операции с объектами класса Sales_data
std::string isbn() const { return bookNo; }
Sales_data& combine(const Sales_data&);
double avg_price() const;
// те же переменные-члены, что и в p. 2.6.1
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
// функции интерфейса класса Sales_data, не являющиеся его членами
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
Функции, определенные в классе, неявно являются встраиваемыми (см. раздел 6.5.2).
Определение функций-членовХотя каждый член класса должен быть объявлен в самом классе, тело функции-члена можно определить либо в, либо вне тела класса. Функция isbn() определяется в классе Sales_data, а функции combine() и avg_price() вне его.
Сначала рассмотрим функцию isbn(), возвращающую строку и имеющую пустой список параметров:
std::string isbn() const { return bookNo; }
Как и у любой функции, тело функции-члена является блоком. В данном случае блок содержит один оператор return, возвращающий значение переменной-члена bookNo объекта класса Sales_data. Интересно, как эта функция получает объект, член bookNo которого следует выбрать?
Указатель thisДавайте снова рассмотрим вызов функции-члена isbn():
total.isbn()
Здесь для вызова функции-члена isbn() объекта total используется точечный оператор (см. раздел 4.6).
За одним исключением, рассматриваемым в разделе 7.6, вызов функции-члена осуществляется от имени объекта. Когда функция isbn() обращается к члену класса Sales_data (например, bookNo), она неявно обращается к членам того объекта, из которого была вызвана. В этом вызове функции isbn(), когда она возвращает значение члена bookNo, речь идет о члене total.bookNo.
Функция-член способна обратиться к тому объекту, из которого она была вызвана, благодаря дополнительному неявному параметру this. Когда происходит вызов функции-члена, указатель this инициализируется адресом объекта, из которого была вызвана функция. Рассмотрим следующий вызов:
total.isbn()
Здесь компилятор присваивает адрес объекта total указателю this и неявно передает его как параметр функции isbn(). Компилятор как бы переписывает этот вызов так:
// псевдокод, в который преобразуется вызов функции-члена
Sales_data::isbn(&total)
Этот код вызывает функцию-член isbn() класса Sales_data, передав адрес объекта total.
В функции-члене можно обратиться непосредственно к членам объекта, из которого она была вызвана. Для использования членов объекта, на который указывает указатель this, можно не использовать оператор доступа к члену. Любое непосредственное использование члена класса подразумевает использование указателя this. Таким образом, когда функция isbn() использует переменную bookNo, она неявно использует член объекта, на который указывает указатель this. Это аналогично синтаксису this->bookNo.
Параметр this определяется неявно и автоматически. Кроме того, определить параметр или переменную по имени this самому нельзя, но в теле функции-члена его использовать можно. Вполне допустимо, хоть и не нужно, определить функцию isbn() так:
std::string isbn() const { return this->bookNo; }
Поскольку указатель this всегда предназначен для обращения к "этому" объекту, он является константным (см. раздел 2.4.2). Нельзя изменить адрес, хранящийся в указателе this.
Константные функции-членыЕще одним важным моментом функции-члена isbn() является ключевое слово const, расположенное за списком параметров. Оно применяется для модификации типа неявного указателя this.
По умолчанию указатель this имеет тип константного указателя на неконстантную версию типа класса. Например, типом по умолчанию указателя this в функции-члене Sales_data является Sales_data *const. Хоть указатель this и неявен, он подчиняется обычным правилам инициализации, согласно которым (по умолчанию) нельзя связать указатель this с константным объектом (см. раздел 2.4.2). Следствием этого факта, в свою очередь, является невозможность вызвать обычную функцию-член для константного объекта.
Если бы функция isbn() была обычной и если бы указатель this был обычным параметром типа указателя, то мы объявили бы его как const Sales_data *const. В конце концов, тело функции isbn() не изменяет объект, на который указывает указатель this; таким образом, эта функция стала бы гибче, если бы указатель this был указателем на константу (см. раздел 6.2.3).
Однако указатель this неявный и не присутствует в списке параметров, поэтому нет места, где можно было бы указать, что он должен быть указателем на константу. Язык решает эту проблему, позволяя разместить ключевое слово const после списка параметров функции-члена. Это означает, что указатель this является указателем на константу. Функции-члены, использующие ключевое слово const таким образом, являются константными функциями-членами (const member function).
Тело функции isbn() можно считать написанным так:
// псевдокод, иллюстрирующий использование неявного указателя
// этот код недопустим: нельзя самому явно определить этот указатель
// обратите внимание, что это указатель на константу, поскольку isbn()
// является константным членом класса
std::string Sales_data::isbn(const Sales_data *const this)
{ return this->isbn; }
Тот факт, что this является указателем на константу, означает, что константные функции-члены не могут изменить объект, для которого они вызваны. Таким образом, функция isbn() может читать значения переменных- членов объектов, для которых она вызывается, но не изменять их.
Константные объекты, ссылки и указатели на константные объекты могут вызывать только константные функции-члены
Область видимости класса и функции-членыПомните, что класс сам является областью видимости (см. раздел 2.6.1). Определения функций-членов класса находятся в области видимости самого класса. Следовательно, использованное функцией isbn() имя bookNo относится к переменной-члену, определенной в классе Sales_data.
Следует заметить, что функция isbn() может использовать имя bookNo, несмотря на то, что оно определено после функции isbn(). Как будет описано в разделе 7.4.1, компилятор обрабатывает классы в два этапа — сначала объявления членов класса, затем тела функций-членов, если таковые вообще имеются. Таким образом, тела функций-членов могут использовать другие члены своих классов, независимо от того, где именно в классе они определены.
Определение функции-члена вне классаПодобно любой другой функции, при определении функции-члена вне тела класса ее определение должно соответствовать объявлению. Таким образом, тип возвращаемого значения, список параметров и имя должны совпадать с объявлением в теле класса. Если член класса был объявлен как константная функция, то в определении после списка параметров также должно присутствовать ключевое слово const. Имя функции-члена, определенное вне класса, должно включить имя класса, которому она принадлежит:
double Sales_data::avg_price() const {
if (units_sold)
return revenue/units_sold;
else
return 0;
}
Имя функции, Sales data::avg_price(), использует оператор области видимости (см. раздел 1.2), чтобы указать, что определяемая функция по имени avg_price объявлена в пределах класса Sales_data. Как только компилятор увидит имя функции, остальная часть кода интерпретируется как относящаяся к области видимости класса. Таким образом, когда функция avg_price() обращается к переменным revenue и units_sold, она неявно имеет в виду члены класса Sales_data.

