类模板泛化编译错误的问题

问题出现的背景

今天在写代码的时候,使用模板泛化,为了让类的代码封装更好,便将类的声明都放在了一个名为 heap.h 的头文件中,将实现的方法写到了 heap.cpp 文件中。

代码是一个大顶堆的数据结构。

问题说明

如下:
heap.h

#pragma once

#include <vector>


template <typename T>
class heap
{
public:
	heap(std::vector<T> v);
	~heap() {};
	
	void insert_heap(T val);
	T pop_heap();

private:
	std::vector<T> a;


	void make_heap();
	void adjust_heap(int index);
};

heap.cpp:

#include "heap.h"
#include <vector>

using namespace std;

template <typename T>
heap<T>::heap(std::vector<T> v) : a(v) {
	T tmp;
	a.insert(a.begin(),tmp);
	make_heap();
}


template <typename T>
void heap<T>::make_heap()
{
	int length = a.size();
	int deaf = length / 2; //取出第一个叶子节点
	while (deaf>0) {
		adjust_heap(deaf);
		deaf--;
	}
}


template <typename T>
void heap<T>::adjust_heap(int index)
{
	int length = a.size();
	while (index < length/2) {
		if (index * 2 + 1 < length 
			&& a[index * 2] > a[index * 2 + 1] 
			&& a[index * 2] > a[index]) {
			T tmp = a[index];
			a[index] = a[index * 2];
			a[index * 2] = tmp;
			index = index * 2;
		}
		else if (index * 2 + 1 < length && 
			a[index * 2] <= a[index * 2 + 1] && 
			a[index * 2 + 1] > a[index]) {
			T tmp = a[index];
			a[index] = a[index * 2 + 1];
			a[index * 2 + 1] = tmp;
			index = index * 2 + 1;
		}
		else if (index * 2 + 1 == length && a[index * 2] > a[index]) 
		{
			T tmp = a[index];
			a[index] = a[index * 2];
			a[index * 2] = tmp;
			break;
		}
		else
			break;
	}
}


template <typename T>
void heap<T>::insert_heap(T val) {
	a.push_back(val);
	int length = a.size() - 1;
	while (length > 1) 
	{
		if (a[length / 2] < a[length]) 
		{
			T tmp = a[length];
			a[length] = a[length / 2];
			a[length / 2] = tmp;
			length = length / 2;
		}
		else
			break;		//当前节点小于等于父节点:终止
	}
}

template<typename T>
T heap<T>::pop_heap() {
	int length = a.size();
	T tmp = a[1];				//将最大节点放到末尾
	a[1] = a[length - 1];
	a.pop_back();
	adjust_heap(1);
	return tmp;
}

main.cpp

#include "heap.h"
#include <iostream>
#include <vector>

using namespace std;


int main()
{
	vector<int> a = { 4,2,6,8,12,60,83,5 };

	heap<int> test(a);
	cout << test.pop_heap() << endl;
	cout << test.pop_heap() << endl;
	cout << test.pop_heap() << endl;

	test.insert_heap(99);
	cout << test.pop_heap() << endl;


	system("pause");
	return 0;
}

报出下面的编译错误:

源.obj : error LNK2019: 无法解析的外部符号 “public: __thiscall heap::heap(class std::vector<int,class std::allocator >)” (??0?heap@H@@QAE@V?heap@H@@QAE@V?heap@H@@QAE@V?vector@HV?KaTeX parse error: Expected group after '_' at position 93: … "public: void _̲_thiscall heap<…heap@H@@QAEXH@Z),该符号在函数 _main 中被引用
源.obj : error LNK2019: 无法解析的外部符号 “public: int __thiscall heap::pop_heap(void)” (?pop_heap@?$heap@H@@QAEHXZ),该符号在函数 _main 中被引用
1>D:\2. MyProject\c++剑指offer\剑指offer2\Debug\heap.exe : fatal error LNK1120: 3 个无法解析的外部命令

遇到这个问题刚开始是崩溃的,感觉自己写的明明没有问题,叫来了几个小伙伴都没有把问题解决掉,因为大家平时写泛化类都是写到一个h文件中,今天差了一下午才找到解决问题的方法:

问题的解决

类的声明和实现,分别在不同的文件下,需要增加一个hpp文件支持。或者尽量将模板函数与模板友元放在一个文件下。

  • 类的声明与函数的声明写在.h文件
  • 类的实现及函数的实现写在.cpp文件
  • 将.cpp文件改成.hpp文件
  • 在主函数中调用.hpp文件,而不是引用.h文件

于是将 heap.cpp 改成 heap1.hpp 编译通过,注意:mian.cpp 中引用 heap1.hpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值