c++模板类链表链接错误?

我想实现一个模板链表,但是每次都报链接错误,问题在LinkList模板类的模板成员函数调用时,什么原因百思不得其解。

//LinkList.h
#ifndef LINKLIST_H
#define LINKLIST_H
#include<iostream>
using namespace std;

template<typename S>
struct Node{       //模板结构体
    Node():data(),next(NULL){}
    S data;
    Node *next;
};

template<typename T>
class LinkList{
    public:
        LinkList(){
            cout<<"I am inside."<<endl;
            head = new Node<T>();
            end = head;
        }
    public:
        void push_head(void);
    private:
        Node<T> *head;
        Node<T> *end;
}; 
#endif

//LinkList.cpp
#include<iostream>
#include"LinkList.h"

template<typename T>
void LinkList<T>::push_head(void){
    cout<<"I am push_head."<<endl;
}

//main.cpp
#include <iostream>
#include"LinkList.h"

int main(int argc, char** argv) {
    LinkList<int> temp;
    temp.push_head();
}

查询了c++primer和文心一言,没有答案。

阅读 728
avatarAI BotBETA

回答

问题出在你的模板类实现方式上。C++ 模板需要在编译时知道它们的完整定义,因此模板类的实现通常应该放在头文件中,而不是单独的 .cpp 文件中。

LinkList.cpp 中的模板成员函数 push_head 的实现移动到 LinkList.h 文件中,就可以解决链接错误的问题。以下是修改后的代码:

// LinkList.h
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
using namespace std;

template<typename S>
struct Node {       // 模板结构体
    Node(): data(), next(NULL) {}
    S data;
    Node *next;
};

template<typename T>
class LinkList {
public:
    LinkList() {
        cout << "I am inside." << endl;
        head = new Node<T>();
        end = head;
    }

    void push_head(void);

private:
    Node<T> *head;
    Node<T> *end;
};

// 将 push_head 的实现移动到头文件中
template<typename T>
void LinkList<T>::push_head(void) {
    cout << "I am push_head." << endl;
}

#endif

// main.cpp 保持不变
#include <iostream>
#include "LinkList.h"

int main(int argc, char** argv) {
    LinkList<int> temp;
    temp.push_head();
    return 0;
}

这样,当你编译 main.cpp 时,编译器可以访问 LinkList<T>::push_head 的完整定义,从而避免链接错误。

2 个回答

将模板函数的实现移动到头文件中,保证在模板实例化时编译器可以访问完整的实现。

#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
using namespace std;

template<typename S>
struct Node {  // 模板结构体
    Node() : data(), next(nullptr) {}
    S data;
    Node* next;
};

template<typename T>
class LinkList {
public:
    LinkList() {
        cout << "I am inside." << endl;
        head = new Node<T>();
        end = head;
    }

    void push_head() {  // 将实现移动到头文件
        cout << "I am push_head." << endl;
    }

private:
    Node<T>* head;
    Node<T>* end;
};

#endif

LinkList.cpp 文件不再需要,直接删除即可

如果一定要把模板实现放在 .cpp 文件中,可以通过显式实例化解决。例如,在 LinkList.cpp 中添加:

template class LinkList<int>;

但这种方法仅适用于有限的、预先确定的模板参数类型(如 int 或 double),并不通用。

问题解决了,由于c++模板只在调用时才实例化,因此在main.cpp中未包含LinkList.cpp文件,仅包含了LinkList.h文件,所以在项目编译时未能实例化模板成员函数,调用时找不到该函数的定义。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏