2

我正在尝试将函数指针传递给类的构造函数。但是,当我尝试编译代码时,出现错误。代码和错误是:

快速查找.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*))'错误。我无法弄清楚问题...请帮助。

4

3 回答 3

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);
};

在你的情况下,它模板化的类,但这个函数不是。而且,模板函数必须在头文件中定义,以便包含它们的文件可以看到代码并替换参数类型。

于 2013-04-06T15:10:18.890 回答
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);
}
于 2013-04-06T16:56:30.257 回答
0

编译器想知道在编译模板类方法时将从模板类中实例化哪些类型的对象。因此,可能会出现编译时或链接时错误。 更多地解释了各种错误及其原因。

#include "quickfind.cpp"经过一些努力,在我的情况下添加头文件的末尾。

于 2013-04-06T16:49:21.443 回答