Связывание файлов в 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, сделайте следующее:

  1. В filename.cpp:
#include <iostream>  
#include <myclass.h>  
//..source code.  
  1. В 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() не упоминается нигде по всему скомпилированному коду.