我正在尝试将函数指针传递给类的构造函数。但是,当我尝试编译代码时,我收到一个错误。代码和错误是:
quickfind.h
#ifndef QUICKFIND_H
#define QUICKFIND_H
#endif // QUICKFIND_H
template <class T>
class QuickFind
{
private:
int size;
int *array;
int (*giveIndex)(const void *a);
public:
QuickFind<T>(int n,int (*ptr)(const void *));
void connect (const T* u,const T* v);
bool isConnected(const T* u,const T* v);
};
文件quickfind.cpp中的构造函数定义
template <class T>
QuickFind<T>::QuickFind(int n,int (*ptr)(const void *))
{
size=n;
array=new int[n];
giveIndex=ptr;
for(int i=0;i<n;i++)
{
array[i]=i;
}
}
在我的主要功能文件中:
int giveIndex (const void *ptr)
{
temp *tptr=(temp*)ptr;
return tptr->getA();
}
int main()
{
QuickFind<temp> *qf=new QuickFind<temp>(10,giveIndex);
}
在这里,我收到'undefined reference to QuickFind<temp>::QuickFind(int, int (*)(void const*))'
错误。我无法弄清楚问题......请帮助。
答案 0 :(得分:2)
有一件事是错的,你不需要构造函数:
template <class T>
class QuickFind
{
private:
int size;
int *array;
int (*giveIndex)(const void *a);
public:
QuickFind(int n,int (*ptr)(const void *)); /// <---- here, no <T>
void connect (const T* u,const T* v);
bool isConnected(const T* u,const T* v);
};
在你的情况下,它模板化的类,但这个功能不是。并且,必须在头文件中定义模板函数,以便包含它们的文件可以查看代码并替换参数类型。
答案 1 :(得分:2)
将以下所有内容放入一个CPP文件中以查看其是否有效。如其他注释中所述,对于模板化类,您必须将整个定义放在头文件中。不要将函数声明与其定义分离为单独的CPP文件。在这种情况下,将一个CPP文件中的整个实现用于相同的目的。
我对您的代码进行了一些更改,以使其类型安全,内存泄漏安全且异常安全。例如,我用std :: vector替换了动态分配的数组。 std :: vector具有您需要的所有功能,但为您管理内存,并在您的课程超出范围时进行清理。
#include <vector>
#include <iostream>
#include <functional>
template <typename T>
class QuickFind
{
private:
std::vector<int> data;
std::function<int (const T&)> func;
public:
QuickFind(int n, std::function<int (const T&)> f) : data(n), func(f)
{
int i = 0;
for(auto it = data.begin(); it != data.end(); ++it)
data[i]=i++;
}
void connect (const T& u, const T& v)
{
std::cout << func(u) << "\n";
std::cout << func(v) << "\n";
}
bool isConnected(const T* u,const T* v);
};
class temp
{
int val;
public:
temp(int i) : val(i)
{}
int getA() const
{
return val;
}
};
int giveIndex (const temp &t)
{
return t.getA();
}
int main()
{
temp t1(5), t2(10);
QuickFind<temp> qf1(10,giveIndex);
qf1.connect(t1, t2);
// this example uses a lambda as the callback
auto giveIndex2 = [](const temp& t) { return t.getA(); };
QuickFind<temp> qf2(20, giveIndex2);
qf2.connect(t1, t2);
}
答案 2 :(得分:0)
编译器想要在编译模板类方法时知道将从模板类实例化哪些类型的对象。因此,可能会出现编译时或链接时错误。 This更多地解释了各种错误及其原因。
在头文件末尾添加#include "quickfind.cpp"
在我的案例中经过一番努力。