Почему определения статической членской функции не имеют ключевое слово "статический"?
По эта ссылка на ключевое слово '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) или может быть уже скомпилирована (из разделяемых библиотек или объектных файлов).
Теперь, возвращаясь к вашему вопросу, когда вы объявляете что-то статичным, это не связано с реализацией, а связано с тем, как компилятор видит объявление при компиляции кода. Например, если вы помечаете функции в исходных файлах "статические", то это бессмысленно, потому что эту информацию нельзя переносить на скомпилированные объекты и разделяемые библиотеки. Зачем это позволить? Наоборот, это может вызвать только двусмысленность.
По той же причине параметры по умолчанию должны входить в заголовок, а не в исходные файлы. Поскольку исходные файлы (содержащие реализации) не могут переносить информацию о параметрах по умолчанию в скомпилированный объект.