Mih*_*rad 7 c c++ class undefined-reference template-classes
当我在我的main函数中调用模板类"add"和"greater"中的两个函数时,我一直得到未定义的引用.
所以,我有:number.h
#ifndef NUMBER_H
#define NUMBER_H
template <class T>
class number {
public:
T x;
T y;
number (int a, int b){
x=a; y=b;}
int add (T&);
T greater ();
};
#endif
Run Code Online (Sandbox Code Playgroud)
number.cpp
#include "number.h"
template <class T>
int number<T>::add (T& rezAdd){
rezAdd = x+y;
return 1;
}
template <class T>
T number<T>::greater (){
return x>y? x : y;
}
Run Code Online (Sandbox Code Playgroud)
我的主文件是:resolver.cpp
#include <stdio.h>
#include <stdlib.h>
#include "number.h"
int main (int argc, char **argv) {
int aux;
number<int> c(3,5);
c.add(aux);
printf ("number added [%d]\n", c.add(aux));
printf ("greater number: [%d]\n", c.greater());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不断得到的错误是:
g++ -Wall -o tema1 resolver.cpp number.cpp
/tmp/ccX483J4.o: In function `main':
resolver.cpp:(.text+0x34): undefined reference to `number<int>::add(int&)'
resolver.cpp:(.text+0x47): undefined reference to `number<int>::add(int&)'
resolver.cpp:(.text+0x64): undefined reference to `number<int>::greater()'
collect2: ld returned 1 exit status
make: *** [all] Error 1
Run Code Online (Sandbox Code Playgroud)
我在这里先向您的帮助表示感谢!
你的课名错了.你的类被命名为cai您所有的功能都属于一个名为类number:http://ideone.com/ZayX0c
还有一件事......你不能在.cpp文件中有模板.模板函数/定义与类声明一起进入标题.这是您的未定义函数错误的原因.非模板函数放在.cpp中.
#include <cstdio>
#include <cstdlib>
template <class T>
class number {
public:
T x;
T y;
number (int a, int b){
x=a; y=b;}
int add (T&);
T greater ();
};
template <class T>
int number<T>::add (T& rezAdd){
rezAdd = x+y;
return 1;
}
template <class T>
T number<T>::greater (){
return x>y? x : y;
}
int main (int argc, char **argv) {
int aux;
number<int> c(3,5);
c.add(aux);
printf ("number added [%d]\n", c.add(aux));
printf ("greater number: [%d]\n", c.greater());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
add将和greater函数模板的定义移至您的number.h.
请记住,add和greater不是函数,它们是函数模板。要创建实际的函数,编译器必须实例化特定类型的模板,例如int,并且只有在发现需要实例时能够访问模板的定义时才能执行此操作。
当您编译 时number.cpp,编译器可以访问模板的定义,但它看不到任何需要特定实例(例如number<int>)的代码,因此它不会生成实例。
当您编译时resolver.cpp,编译器发现它需要实例化该int类型的这些模板,但它不能,因为它没有它们的定义。因此它生成“外部引用”,基本上是告诉链接器在其他目标文件中查找这些函数。
结果是函数模板没有在任一目标文件 \xe2\x80\x94 中实例化,其中一个是因为编译器不知道它应该实例化,而另一个是因为它无法 \xe2\ x80\x94,因此当链接器寻找它们(以解析这些外部引用)时,它找不到它们。这就是您收到错误的原因。
\n\n将模板函数定义移动到标头中使编译器在编译时可以看到它们main.cpp,因此它能够为该int类型实例化这些函数。.cpp正是出于这个原因,函数模板通常需要在头文件而不是文件中定义。
我更喜欢在.cpp文件中包含我的所有函数,无论它们是模板函数还是常规函数。有一种方法可以用一些基本的#ifndef魔法来做到这一点。您可以执行以下操作:
主程序
#include "myclass.hpp"
int main()
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我的类.hpp
#ifndef MYCLASS
#define MYCLASS
template<class T>
class MyClass
{
T val;
public:
MyClass(T val_);
}
#define MYCLASS_FUNCTIONS
#include "myclass.cpp"
#endif
Run Code Online (Sandbox Code Playgroud)
我的类.cpp
#ifndef MYCLASS_FUNCTIONS
#include "myclass.hpp"
// regular functions:
// ...
#else
// template functions:
template<class T>
MyClass<T>::MyClass(T val_)
:val(val_)
{}
// ...
#endif
Run Code Online (Sandbox Code Playgroud)
这是预编译器如何看待它。我们有两个.cpp文件。
myclass.hppMYCLASS未定义,它是myclass.cppMYCLASS_FUNCTIONSMYCLASS_FUNCTIONS已定义,它是MYCLASS_FUNCTIONS已定义,它不是myclass.hppMYCLASS未定义,它是myclass.cppmyclass.hpp再次包括MYCLASS是定义的所以在里面什么都不做,回到myclass.cppMYCLASS_FUNCTIONS已定义,它是