Статическая функция, объявленная, но не определенная в С++
Я получаю сообщение об ошибке из следующего кода с помощью С++.
main.cpp
#include "file.h"
int main()
{
int k = GetInteger();
return 0;
}
file.h
static int GetInteger();
file.cpp
#include "file.h"
static int GetInteger()
{
return 1;
}
Ошибка, которую я получаю:
Error C2129: static function 'int GetInteger(void)' declared but not defined.
Я прочитал знаменитую статью "Организация файла кода на C и С++" , но не понимаю, что не так с этим кодом.
Ответы
Ответ 1
В С++, static
в области глобального/пространства имен означает, что функция/переменная используется только в блоке перевода, где она определена, а не в других единицах перевода.
Здесь вы пытаетесь использовать статическую функцию из другой единицы перевода (Main.cpp
), чем та, в которой она определена (File.cpp
).
Удалите static
, и он должен работать нормально.
Ответ 2
Изменить
static int GetInteger();
к
int GetInteger();
static
в этом случае дает метод внутренний linkeage, что означает, что вы можете использовать его только в единицах перевода, где вы его определяете.
Вы определяете его в File.cpp
и пытаетесь использовать его в main.cpp
, но у main нет определения для него, так как вы объявили его static
.
Ответ 3
Поскольку в этом случае static
означает, что имя функции имеет
внутренняя связь; что GetInteger
в одной единицы перевода не имеет отношения
до GetInteger
в любой другой единицы перевода. Ключевое слово static
перегружен: в некоторых случаях это влияет на продолжительность жизни, а в других - на привязку.
Это особенно смущает здесь, потому что "статический" также является именем
продолжительность жизни. Функции и данные, объявленные в области пространства имен, всегда
имеют статическое время жизни; когда static
появляется в их объявлении, это
вызывает внутреннее связывание, а не внешнее.
Ответ 4
Если все в одной и той же системе перевода, оно должно работать.
Вероятно, вы не компилировали File.cpp в тот же блок, что и Main.cpp.
g++ -Wall File.cpp Main.cpp
Если каждый файл скомпилирован отдельно, функция должна быть сделана extern
, которая будет использоваться из
другая единица перевода.
extern int GetInteger();
что совпадает с
int GetInteger();
Ответ 5
функции, объявленные как static arelocal к содержащемуся файлу. Поэтому вам нужно определить функцию в том же файле, что и те, кто ее называет. Если вы хотите сделать его вызываемым из другого файла, вы НЕ должны объявлять его как статический.
Ответ 6
С моей точки зрения, статические функции - это имя, искаженное именем файла, в котором они определены, поэтому, когда вы включаете file.h в main.cpp, GetInteger() получает mangled с main.cpp, хотя вы определили GetInteger() в файле .cpp, но поскольку он статичен, он тоже искажается, а линкер не может найти определение GetInteger(), поскольку никакая функция этим именем не существует.
Я считаю, что извлеченный урок не объявляет статические функции в заголовочном файле, поскольку они не предназначены для части интерфейса.