Обязательно ли определять список инициализации в заголовочном файле?

Недавно я создал класс Square:

========= Заголовочный файл ======

class Square
{
    int m_row;
    int m_col;

public:
    Square(int row, int col): m_row(row), m_col(col) 
};

========== cpp file ======

#include "Square.h"

Square::Square(int row, int col)
{
    cout << "TEST";
}

но тогда я получаю много ошибок. Если я удаляю файл cpp и изменяю заголовочный файл на:

========= Заголовочный файл ======

class Square
{
    int m_row;
    int m_col;

public:
    Square(int row, int col): m_row(row), m_col(col) {};
};

это соответствует без ошибок. Означает ли это, что список инициализации должен появиться в заголовочном файле?

5 ответов

Решение

Вы можете иметь

============== заголовочный файл ================

class Square
{
    int m_row;
    int m_col;

public:
    Square(int row, int col);
};

================== cpp ====================

Square::Square(int row, int col):m_row(row), m_col(col) 
{}

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

public:
    Square(int row, int col): m_row(row), m_col(col) {};

или в файле.cpp:

Square::Square(int row, int col) : m_row(row), m_col(col) 
{
    // ...
}

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

public:
    Square(int row, int col);

Список инициализации появляется с определением конструктора, а не с объявлением, которое не является определением. Итак, ваши варианты:

Square(int row, int col): m_row(row), m_col(col) {}; // ctor definition

в определении класса или иначе:

Square(int row, int col); // ctor declaration

в определении класса и:

Square::Square(int row, int col): m_row(row), m_col(col) {} // ctor definition

в другом месте. "В другом месте" разрешено находиться в шапке, если вы сделаете это inline,

Не является обязательным требованием. Это также может быть реализовано в исходном файле.

// In a source file
Square::Square(int row, int col): m_row(row), 
                                  m_col(col) 
{}

Этот вид инициализации переменной называется списком инициализации члена. Список инициализации элемента может использоваться в заголовочном файле или исходном файле. Это не имеет значения. Но конструктор должен иметь определение, когда вы инициализируете его в заголовочном файле. Вы можете обратиться к C++ List Initialization List для получения более подробной информации.

Другие вопросы по тегам