Почему статическая функция-член только объявляется статичной в определении класса, а не в ее собственном определении?

Во время реализации класса для создания/обновления полей на экране я хотел добавить статическую функцию-член, которая не перекрывает видимые в настоящее время поля (принимая информацию из массива статических указателей во все видимые в настоящее время поля)

Мой начальный код имел следующую структуру:

class Box
{
public:
    // ...
    static void arrangeOverlappingBoxes();
};

static void Box::arrangeOverlappingBoxes()
{
    // ...
}

Я был очень удивлен, что это вызвало ошибку C2724: "static" не следует использовать для функций-членов, определенных в области файлов.

С некоторыми пробными версиями Google и ошибкой я понял, что мое определение функции должно потерять ключевое слово static, то есть оно должно быть

void Box::arrangeOverlappingBoxes()
{
    // ...
}

Но я не знаю, что может быть причиной этого. Кажется, это так асимметрично и сбивает с толку, что у него есть другой заголовок функции для его объявления в определении класса и его собственном определении. Есть ли причина для этого?

Ответ 1

Определение вашего класса (в файле заголовка) предоставит функции с любыми необходимыми параметрами:

  • статичным
  • встраиваемыми
  • виртуальный

Учитывая, что каждый последующий объект будет рассматривать определение вашего класса с помощью .h, тогда имеет смысл, что эти свойства будут определены там.

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

Нет смысла переопределять эти свойства в вашем теле реализации.

Признание функций в файлах .h и .cpp фактически приведет к возникновению проблем. Представьте себе этот сценарий: вы объявляете функцию виртуальной в файле .h и статичным в файле .cpp. Что сделает компилятор этой функцией? виртуальный или статический? (или, скорее, ошибка компиляции, но ошибка компилятора просто заставит вас сопоставить в вашем .cpp файле объявление в заголовке. Вы не можете перегружать функцию в соответствии с "статическим" или "виртуальным" ).