线性表-链式存储结构(单链表)

本文探讨了类模板在不同文件中定义与实现时遇到的链接错误问题,并提供了一个具体的例子来说明如何解决这一问题。文章指出,类模板的声明与实现不能分离,否则会导致编译器在模板实例化时找不到相应代码从而引发链接错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要注意的问题:类模板无法分开链接问题。


类模板在编译的时候没有错误,但是在链接过程中会报错

error LNK2019: unresolved external symbol "public: __thiscall LinkList<int>::~LinkList<int>(void)" (??1?$LinkList@H@@QAE@XZ) referenced in function _main

这是由于类模板的声明和实现不能放在不同的文件中,即类模板的声明和实现是不能分离的。因为类模板和函数模板都不是真正的定义,真正的定义是在模板实体化的时候由编译器完成的。如果将模板的定义部分和实现部分分离开来,编译器真正要去完成模板实体化的时候就会因为找不到相应的代码而发生链接错误。



代码如下:

//linkList.h

#ifndef LINKLIST_H_H
#define LINKLIST_H_H

//#include 
using namespace std;

template
struct Node
{
	T data;
	Node * next;
};

template
class LinkList
{
private:
	Node * head;
public:
	LinkList();
	LinkList(T dataArray[], int n);
	~LinkList();
	int ListLength();
	T GetItem(int pos);
	int LocateItem(T item);
	void PrintLinkList();
	void InsertItem(int pos, T item);
	T DeleteItem(int pos);
	void InvertItem();//反转
	void Merge(LinkList &linklist);//合并
};


#endif
//linklist.cpp
#ifndef LINKLIST_CPP_CPP //为了解决类模板无法分开链接问题,需要include该实现文件,并注意重复包含问题。
#define LINKLIST_CPP_CPP

#include "linklist.h"
#include 

template
LinkList::LinkList()
{
	head = new Node(T);
	head->next = NULL;
}

template
LinkList::LinkList(T dataArray[], int n)
{
	Node * currentNode, * newNode;
	head = new Node;
	currentNode = head;
	for(int i = 0; i < n; ++i)
	{
		newNode = new Node;
		newNode->data = dataArray[i];
		currentNode->next = newNode;
		currentNode = newNode;
	}
	currentNode->next = NULL;
}

template
LinkList::~LinkList()
{
	Node * ptr, * pTemp;
	ptr = head;
	while(ptr)
	{
		pTemp = ptr;
		ptr = ptr->next;
		delete pTemp;
	}
	head = NULL;
}

template
int LinkList::ListLength()
{
	Node * ptr;
	int count = 0;
	ptr = head->next;
	while(ptr)
	{
		ptr = ptr->next;
		++count;
	}
	return count;
}

template
T LinkList::GetItem(int pos)
{
	Node * ptr;
	ptr = head->next;
	int position = 1;
	while(ptr && (position < pos))
	{
		ptr = ptr->next;
		++position;
	}
	if(!ptr)
	{
		cerr<<"Cannot find the Item."<data;
	}
}

template
int LinkList::LocateItem(T item)
{
	Node * ptr;
	ptr = head->next;
	int position = 1;
	while(ptr && (ptr->data != item))
	{
		ptr = ptr->next;
		++position;
	}
	if(ptr)
	{
		return position;
	}
	else
	{
		return 0;
	}
}

template
void LinkList::PrintLinkList()
{
	Node * ptr;
	ptr = head->next;
	while(ptr)
	{
		cout<data<next;
	}
}

template
void LinkList::InsertItem(int pos, T item)
{
	Node * ptr, * pTemp;
	ptr = head;
	int position = 1;
	while(ptr && (position < pos))
	{
		ptr = ptr->next;
		++position;
	}
	if(!ptr)
	{
		cerr<<"Cannot insert in this position."<;
		pTemp->data = item;
		pTemp->next = ptr->next;
		ptr->next = pTemp;
	}
}

template
T LinkList::DeleteItem(int pos)
{
	Node * ptr, * pTemp;
	T item;
	ptr = head;
	int position = 1;
	while(ptr && (position < pos))
	{
		ptr = ptr->next;
		++position;
	}
	if(!ptr || !ptr->next)
	{
		cerr<<"Cannot fine item need to delete in this position."<next;
		item = pTemp->data;
		ptr->next = pTemp->next;
		delete pTemp;
		return item;
	}
}

template
void LinkList::InvertItem()
{
	Node *ptr, *pTemp;
	ptr = head->next;
	head->next = NULL;
	while(ptr != NULL)
	{
		pTemp = ptr;
		ptr = ptr->next;
		pTemp->next = head->next;
		head->next = pTemp;
	}
}

template
void LinkList::Merge(LinkList &linklist)
{
	Node *p1,*p2,*p3;
	p1 = this->head->next;
	p2 = linklist.head->next;
	p3 = this->head;

	while((p1 != NULL) && (p2 != NULL))
	{
		if(p1->data < p2->data)
		{
			p3->next = p1;
			p1 = p1->next;
			p3 = p3->next;
		}
		else
		{
			p3->next = p2;
			p2 = p2->next;
			p3 = p3->next;
		}
	}
	if(!p1)
	{
		p3->next = p1;
	}
	if(!p2)
	{
		p3->next = p2;
	}

	delete linklist.head;
	linklist.head = NULL;
}

#endif
//test.cpp

#include "linklist.h"
#include "linklist.cpp" //类模板无法分开链接
#include 
using namespace std;

int main(int argc, char * argv[])
{
	int array1[] = {1,3,5,7,9};
	int array2[] = {2,4,6,8,10};

	LinkList linklist(array1,5);
	LinkList linklist2(array2,5);

	cout<<"Show all item:"<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值