Связывание файлов в g++
Недавно я попытался скомпилировать программу в g++ (на Ubuntu). Обычно я использую Dev-С++ (в Windows), и он отлично работает там, пока я делаю проект и размещаю там все необходимые файлы.
Ошибка при компиляции программы:
$filename.cpp: undefined reference to '[Class]::[Class Member Function]'
Используемые файлы:
Файл исходного кода (.cpp) с основной функцией.
Файл заголовка с прототипами функций.
Файл .cpp с определениями для каждой функции.
Любая помощь будет оценена.
Ответы
Ответ 1
Вероятно, вы пытались либо скомпилировать, либо связать, а не просто компилировать исходные файлы или как-то забыть что-то.
Вариант один (все в одной строке, все перекомпилирует все время):
g++ -o myexecutable first.cpp second.cpp third.cpp [other dependencies, e.g. -Lboost, -LGL, -LSDL, etc.]
Вариант 2 (шаг за шагом, если нет -o
), gcc будет повторно использовать имя входного файла и просто изменить расширение, если оно не связано, этот вариант лучше всего использовать для make файлов, позволяет пропустить неизменные части):
g++ -c first.cpp
g++ -c second.cpp
g++ -c third.cpp
g++ -o myexecutable first.o second.o third.o [other dependencies]
Вариант три (некоторые заполнители):
Не перечислите его, но упомянутые выше параметры могут также занять место, например. g++ -c *.cpp
будет компилировать все файлы cpp в текущей директории в файлы o (bject) с тем же именем.
В целом вы не должны слишком беспокоиться об этом, если вам действительно не нужно работать без какой-либо IDE. Если вы не владеете синтаксисом командной строки, сначала придерживайтесь IDE.
Ответ 2
Командная строка gcc должна выглядеть так:
g++ -o myprogram class1.cpp class2.cpp class3.cpp main.cpp
Проверьте, в каком cpp файле определена функция члена класса. Возможно, вы не передали его gcc.
Ответ 3
Вы также можете проверить правильность тегов #include
в filename.cpp
. Предположим, что filename.cpp
использует код, содержащийся в myclass.h
в том же каталоге, что и filename.cpp
. Предположим, что класс, о котором говорит g++, не определен, содержится в myclass.h
и определен в myclass.cpp
. Итак, чтобы правильно включить myclass.h
в filename.cpp
, сделайте следующее:
- В
filename.cpp
:
#include <iostream>
#include <myclass.h>
//..source code.
- В make файле:
filename.o: myclass.C myclass.h filename.cpp
g++ -I./ -c filename.cpp -o filename.o
myclass.o: myclass.C myclass.h
g++ -c myclass.C -o myclass.o
В приведенном выше, обратите внимание на использование -I.
опция при компиляции filename.cpp
. -I<directory>
просит g++
включить путь, следующий за -I
в путь поиска. Таким образом, myclass.h
правильно включен.
В отсутствие дополнительной информации (возможно, источника) трудно с какой-либо точностью сказать, в чем заключается проблема. Все попытки будут, но нанесут удар в темноте.
Ответ 4
Я предполагаю, что вы объявили функцию-член (обычно в файле .h
или .hpp
), но оммитировали соответствующее определение функции-члена (обычно в файле .cpp
).
В С++ можно объявить класс следующим образом:
class foo {
void x();
void y();
}
с файлом cpp, который выглядит так
void foo::x() {
do_something()
}
Обратите внимание: нет foo::y()
.
Это не представляет проблемы для процесса компиляции/связывания, если функция-член foo::y()
не упоминается нигде по всему скомпилированному коду.