Как разбить объявление класса и его реализацию?

В C++, классы могут быть объявлены и реализованы в одном файле или разделены на два файла - заголовочный файл (.h или .hpp) с объявлениями и файл реализации (.cpp) с определениями методов класса.

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

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

Теперь рассмотрим пример деления класса на заголовочный файл и файл реализации. Допустим, у нас есть класс "Person", который хранит информацию о человеке. Мы хотим объявить только методы класса в заголовочном файле, а реализацию оставить в файле реализации.

Первый шаг - создать заголовочный файл "Person.h":

// Person.h

#ifndef PERSON_H
#define PERSON_H

class Person {
public:
    Person();  // конструктор
    ~Person(); // деструктор

    void setName(const std::string& name); // установить имя
    std::string getName() const;           // получить имя

private:
    std::string m_name; // приватная переменная для хранения имени
};

#endif

В данном примере мы объявили класс Person с публичными методами setName, getName, конструктором и деструктором, а также приватным полем m_name для хранения имени. Обратите внимание, что мы используем директивы #ifndef, #define и #endif для предотвращения множественного включения заголовочного файла.

Затем создаем файл реализации "Person.cpp":

#include "Person.h"

Person::Person() {
    // реализация конструктора
}

Person::~Person() {
    // реализация деструктора
}

void Person::setName(const std::string& name) {
    m_name = name;
}

std::string Person::getName() const {
    return m_name;
}

В файле реализации определяем методы класса Person, которые были объявлены в заголовочном файле. Здесь мы также включаем заголовочный файл "Person.h".

Теперь мы можем использовать класс Person, подключив только заголовочный файл "Person.h":

#include "Person.h"

int main() {
    Person person;
    person.setName("John");
    std::string name = person.getName();

    return 0;
}

В данном примере мы создаем объект класса Person, вызываем метод setName для установки имени и метод getName для получения имени.

Таким образом, разделение объявления класса и его реализации на заголовочные файлы и файлы реализации позволяет упорядочить код, ускорить время компиляции и сделать код более модульным.