"undefined reference to" Ubuntu 上的链接
"undefined reference to" linking on Ubuntu
我对C &c++和编译(或者我应该说链接)困了整整2天。任何人给我一个主意都会很感激。下面是错误信息和3个代码文件。这些是我从实际工作中删减到最小的内容,以便你们可以更好地了解。
环境:Ubuntu 10.10, Eclipse Indigo CDT, g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
错误信息:
**** Build of configuration Debug for project SceneRec2 ****
make all
Building file: ../src/AdaBoost.cpp
Invoking: GCC C++ Compiler
g++ -I"/home/ubuntuLove/Documents/workspace_eclipse/SceneRec2/Includes" -I/usr/src/linux-headers-2.6.35-30/arch/um/include/shared -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/AdaBoost.d" -MT"src/AdaBoost.d" -o "src/AdaBoost.o" "../src/AdaBoost.cpp"
Finished building: ../src/AdaBoost.cpp
Building file: ../src/AdaMain.cpp
Invoking: GCC C++ Compiler
g++ -I"/home/ubuntuLove/Documents/workspace_eclipse/SceneRec2/Includes" -I/usr/src/linux-headers-2.6.35-30/arch/um/include/shared -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/AdaMain.d" -MT"src/AdaMain.d" -o "src/AdaMain.o" "../src/AdaMain.cpp"
../src/AdaMain.cpp: In function ‘int main(int, char**)’:
../src/AdaMain.cpp:6: warning: deprecated conversion from string constant to ‘char*’
Finished building: ../src/AdaMain.cpp
Building target: SceneRec2
Invoking: GCC C++ Linker
g++ -o "SceneRec2" ./src/AdaBoost.o ./src/AdaMain.o
./src/AdaMain.o: In function `main':
/home/ubuntuLove/Documents/workspace_eclipse/SceneRec2/Debug/../src/AdaMain.cpp:5: undefined reference to `AdaBoost<double>::AdaBoost()'
/home/ubuntuLove/Documents/workspace_eclipse/SceneRec2/Debug/../src/AdaMain.cpp:6: undefined reference to `AdaBoost<double>::readFromFile(char*)'
/home/ubuntuLove/Documents/workspace_eclipse/SceneRec2/Debug/../src/AdaMain.cpp:8: undefined reference to `AdaBoost<double>::~AdaBoost()'
/home/ubuntuLove/Documents/workspace_eclipse/SceneRec2/Debug/../src/AdaMain.cpp:8: undefined reference to `AdaBoost<double>::~AdaBoost()'
collect2: ld returned 1 exit status
make: *** [SceneRec2] Error 1
**** Build Finished ****
注1。当我在terminal上执行g++时,我收到了相同的结果。
注2。链接器参数中.o文件的路径应该是正确的(./src/###.o)。
AdaBoost.h
#ifndef _ADABOOST_H
#define _ADABOOST_H
#include <iostream>
const double eps = 2.2204e-16;
template<class T>
class AdaBoost
{
int N; //Number of Instances
int D; //Number of Dimensions
int nL; //Number of Learners / Classifiers / Rules
T** fVectors;
int* labels;
void learnRule(int t, double* dist);
double genRule(int t, int* L, double* dist);
public:
//Default Constructor
AdaBoost();
//Constructor
AdaBoost(T** data, int* labels, int n, int d, int nL);
//Train function
void train();
//Test function
void test(double** data, double* pMap);
void test(double** data, double* pMap, int n);
int writeToFile(char* fName);
int readFromFile(char* fName);
//Destructor
~AdaBoost();
};
#endif
AdaBoost.cpp
#include "AdaBoost.h"
#include <fstream>
using namespace std;
template class AdaBoost<double> ;
template<class T>
int AdaBoost<T>::readFromFile(char* fName) {
ifstream inFile;
int temp;
int d, dir;
float thr, wt;
inFile.open(fName);
if (!inFile)
return 0;
inFile >> temp;
this->nL = temp;
int k = 0;
while (!inFile.eof() && k < nL) {
inFile >> d;
inFile >> thr;
inFile >> dir;
inFile >> wt;
k++;
}
inFile.close();
return 1;
}
AdaMain.cpp
#include "AdaBoost.h"
using namespace std;
int main(int argc, char** argv)
{
AdaBoost<double> rdClass;
rdClass.readFromFile("Naerer");
return 0;
}
如果使用显式实例化,则必须在实例化类之前定义成员函数的泛型版本:
template<class T>
int AdaBoost<T>::readFromFile(char* fName) {
// ...
}
template class AdaBoost<double>;
然而,如果你没有一个明确的或紧迫的理由来使用显式实例化,那么就使用其他建议,并在头文件中定义模板。
不能在不同的编译单元中分离模板类的定义和实现。换句话说,AdaBoost<T>
的完整实现应该链接到与main
(使用它的地方)相同的编译单元中。
这通常是固定的#including
的.cpp
文件在你的.hpp
文件的末尾(如果你想保持它们分开),或者只是使用.hpp
文件实现整个类那里。
你有很多问题。
首先,在CPP文件中使用显式实例化的非常规技术。正如其他人指出的那样,惯例(但仅此而已)要求您将实现放在. h文件中以允许泛型实例化。您不必这样做,但是如果您这样做了,readfile()错误就会消失。(作为替代,将AdaBoost<double>
实例化放在AdaBoost::readfile
定义的之后。)
接下来,声明了构造函数和析构函数,但没有定义它们。如果希望使用编译器提供的构造函数和析构函数,则应该删除声明。如果你希望使用自己的构造函数和析构函数,你应该定义它们。
最佳实践是去掉AdaBoost.cpp,并修改AdaBoost.h,使其实现内联在头文件中。(注意,这个最佳实践适用于模板化类;其他建议可能适用于非模板化类
您需要将template<class T>
int AdaBoost<T>::readFromFile(char* fName)
的定义放入AdaBoost.h
中,并从构建中删除AdaBoost.cpp
。
最好将所有模板代码放入头文件中。c++链接器需要消除模板代码的重复实例化,这样你就不会得到"multiply defined symbol"错误。
注:您应该将函数声明为template<class T>
int AdaBoost<T>::readFromFile(const char* fName)
,以消除deprecated conversion from string constant to ‘char*’
警告。该函数不需要更改文件名
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- CMake-按正确顺序将项目与C运行时对象文件链接
- 从链接列表c++中删除一个项目
- 尝试链接我的着色器时,我收到错误代码"error c5145 must write to gl_position"
- 尝试使用 extern "C" 调用 C 中的C++方法,得到"undefined reference to"对象的链接器错误
- 链接器错误:"cannot move location counter backwards (from 200009f8 to 20000800)"
- LD:架构x86_64 clang找不到符号:错误:链接器命令失败,出口代码1(使用-v to See
- 链接链接器/加载器错误时"undefined reference to ..."与拉斯皮康库链接时
- CUDA链接错误(lib to dll)
- 在 c++ 应用程序中使用 libgrib2c,链接器错误"Undefined reference to..."
- 使用模板时出现"undefined reference to"链接器错误
- Eclipse C/C++:外部库的交叉编译链接器错误:Ubuntu VM amd64 to Ubuntu armhf
- 将静态 C 库与C++代码链接时出现"undefined reference to"错误
- 在cygwin中使用clang的神秘链接器错误"undefined reference to `__gxx_personality_v0'"
- 继承链接引发'undefined reference to...' C++
- 与使用 GCC 3.4.6 (libstdc++.so.6.0.13) 生成的 gmock 库链接会产生"undefined reference to... @GLIBCXX_3.4.9"错误
- "undefined reference to" Ubuntu 上的链接
- "Undefined reference to" 链接目标文件时出错
- 链接错误 "undefined reference to `__gxx_personality_v0'" 和 g++
- 使用 llvm::Function::d ump(),链接器可以"undefined reference to `llvm::Value::dump() const'"