Почему определения статической членской функции не имеют ключевое слово "статический"?

По эта ссылка на ключевое слово 'static' в С++:

Статическое ключевое слово используется только с объявлением статического член, внутри определения класса, но не с определением этот статический член.

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

Ответы

Ответ 1

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

Рассмотрим это:

namespace foo {
    static void bar();
}

static void foo::bar() {

}

foo::bar требуется с тем же спецификатором привязки.

Однако для функций-членов static не является спецификатором привязки. Если бы это было разрешено, правильность определения foo::bar будет очень очень зависимой от контекста, чем foo. Запрет static фактически облегчает нагрузку на компилятор.

Расширение его для членов вообще, в отличие от простых функций-членов, является вопросом согласованности.

Ответ 2

Дело в том, что static имеет несколько, очень разных значений:

class Foo {
    static void bar();
}

Здесь ключевое слово static означает, что функция bar связана с классом Foo, но она не вызывается в экземпляре Foo. Этот смысл static сильно связан с ориентацией объекта. Однако декларация

static void bar();

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

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


static имеет еще более четкие значения:

void bar() {
    static int hiddenGlobal = 42;
}

- другое значение, подобное, но не идентичное

class Foo {
    static int classGlobal = 6*7;
}

При программировании слова не всегда одинаковы во всех контекстах.

Ответ 3

Удивительно, но если определение имеет статичное значение, оно может быть интерпретировано как переменная области видимости файла в смысле С.

Ответ 4

Вам нужно понять разницу между декларацией и реализацией, и это ответит на ваш вопрос:

Декларация: как видятся функции и методы С++ перед компиляцией программы. Он помещается в файл заголовка (файл .h).

Реализация: как компилятор связывает объявление с реальной задачей в двоичном коде. Реализация может быть скомпилирована "на лету" (из исходных файлов,.cpp или .cxx или .cc) или может быть уже скомпилирована (из разделяемых библиотек или объектных файлов).

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

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