- •Классы и заголовочные файлы Отделение объявления от реализации
- •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 () {
- •Другие вложенные пользовательские типы данных в классах
Классы и заголовочные файлы
О заголовочных файлах в языке С++ знаем, что объявления функций можно поместить в заголовочные файлы, чтобы затем иметь возможность использовать эти функции в нескольких файлах или даже в нескольких проектах.
Классы в этом плане ничем не отличаются от функций. Определения классов могут быть помещены в заголовочные файлы для облегчения их повторного использования в нескольких файлах или проектах.
Обычно, определение класса помещается в заголовочный файл с тем же именем, что у класса, а методы, определенные вне тела класса, помещаются в файл .cpp с тем же именем, что у класса.
Вот наш класс Date, но уже разбитый на файлы .cpp и .h:
Date.h:
#ifndef DATE_H
#define DATE_H
class Date {
private:
int m_day;
int m_month;
int m_year;
public:
Date (int day, int month, int year);
void SetDate (int day, int month, int year);
Int getDay () {return m_day;}
int getMonth () {return m_month;}
int getYear () {return m_year;}
};
#endif
Date.cpp:
#include "Date.h"
// Конструктор класса Date
Date::Date (int day, int month, int year) {
SetDate (day, month, year);
}
// Метод класса Date
Void Date::SetDate (int day, int month, int year) {
m_day = day;
m_month = month;
m_year = year;
}
Теперь любой другой файл .h или .cpp, который захочет использовать класс Date, сможет просто подключить заголовочный файл: #include "Date.h".
Обратите внимание, Date.cpp также необходимо добавить до компиляции в проект, который использует Date.h, чтобы линкер смог разобраться с реализацией класса Date.
Вопрос №1: «Разве определение класса в заголовочном файле не нарушает правило одного определения?».
Нет. Классы — это пользовательские типы данных, которые освобождаются от определения только в одном месте. Поэтому класс, определенный в заголовочном файле, можно свободно подключать в другие файлы.
Вопрос №2: «Разве определения методов класса в заголовочном файле не нарушает правило одного определения?».
Методы, определенные внутри тела класса, считаются неявно встроенными. Встроенные функции освобождаются от правила одного определения. А это означает, что проблем с определением простых методов (таких как функции доступа) внутри самого класса возникать не должно.
Методы, определенные вне тела класса, рассматриваются, как обычные функции, и подчиняются правилу одного определения, поэтому эти функции должны быть определены в файле .cpp, а не внутри .h. Единственным исключением являются шаблоны функций (но об этом чуть позже).
Параметры по умолчанию
Параметры по умолчанию для методов должны быть объявлены в теле класса (в заголовочном файле), где они будут видны всем, кто подключает этот заголовочный файл с классом.
Библиотеки
Разделение объявления класса и его реализации очень распространено в библиотеках, которые используются для расширения возможностей вашей программы.
Вы также подключали такие заголовочные файлы из Стандартной библиотеки С++, как iostream, string, vector, array и другие.
Обратите внимание, вы не добавляли iostream.cpp, string.cpp, vector.cpp или array.cpp в ваши проекты.
Ваша программа нуждается только в объявлениях из заголовочных файлов, чтобы компилятор смог проверить корректность вашего кода в соответствии с правилами синтаксиса языка C++.
Однако реализации классов, находящихся в Стандартной библиотеке С++, содержатся в предварительно скомпилированном файле, который добавляется на этапе линкинга. Вы нигде не встречаете этот код.
Вне программ с открытым исходным кодом (где предоставляются оба файла: .h и .cpp), большинство сторонних библиотек предоставляют только заголовочные файлы вместе с предварительно скомпилированным файлом библиотеки. На это есть несколько причин:
На этапе линкинга быстрее будет подключить предварительно скомпилированную библиотеку, чем выполнять перекомпиляцию каждый раз, когда она нужна.
Защита интеллектуальной собственности (создатели не хотят, чтобы другие просто «воровали» их код).
Наличие собственных файлов, разделенных на объявление (файлы .h) и реализацию (файлы .cpp), является не только хорошей формой содержания кода, но и упрощает создание собственных пользовательских библиотек.
