如果将类模板的声明和实现写在两个独立的文件中,在构建时会出现“error LNK2019: 无法解析的外部符号 ”的错误。
主要思路是:
- 写类模板时,没有.h和.cpp文件,创建一个命名为 ***.hpp的文件。
- 将声明和实现同时写在里面。
- 调用时添加#include "***.hpp"。
代码示例如下:
- 创建文件AttrTemplateUtil.hpp,将声明和实现同时写在里面
//zhaoanan 创建文件AttrTemplateUtil.hpp
#pragma once
#include <stdio.h>
#include "StdAfx.h"
#include <string.h>
#include "..\tharx\CthEntity.h"
#include "..\tharx\CthRailSlope.h"
#include "..\tharx\CthRailCurves.h"
//#include "..\MongoDBDAO\ObjectPO.h"
#include "ObjectPO.h"
//#include "KiloMiterPostCfg.h"
class __declspec(dllexport) AttrTemplateUtil
{
public:
AttrTemplateUtil::AttrTemplateUtil(void)
{
}
AttrTemplateUtil::~AttrTemplateUtil(void)
{
}
//static CUserSystem mysis;
public:
//使用冒泡排序对向量有小到大排序,冒泡排序的平均时间复杂度o(n^2)
template <class T>
static void sort_Vecdata_S( vector<T *> &railSlope_Vecdata_S )
{
try
{
//上线公里标图元排序x坐标,按照x坐标从小到大排序
T *railSlope1;
int Num3=railSlope_Vecdata_S.size();
for(int i=0;i<Num3-1;i++)
{
//定义标志位
int flag = 1;
for (int j=0;j<Num3-1-i;j++)
{
if(railSlope_Vecdata_S.at(j)->position().x > railSlope_Vecdata_S.at(j+1)->position().x)
{
railSlope1=railSlope_Vecdata_S.at(j);
railSlope_Vecdata_S.at(j)=railSlope_Vecdata_S.at(j+1);
railSlope_Vecdata_S.at(j+1)=railSlope1;
flag = 0;
}
}
//如果当前循环没有发生任何的交换,则以下不需要循环了
if(1 == flag){
break;
}
}
}
catch(...)
{
AfxMessageBox(_T("unknown CException in sort_Vecdata_S")) ;
}
}
//使用快速排序对向量有小到大排序,快速排序的平均时间复杂度O(NlogN)
template <class T>
static void quicksort_Vecdata_S( vector<T *> &railSlope_Vecdata_S, int left, int right)
{
try
{
//上线或者下线公里标图元排序x坐标,按照x坐标从小到大排序
T *pivot;
int arr_size = railSlope_Vecdata_S.size();
//1.计算中间元素的下标,单独保存起来
//printf("%d, %d\n", left, right);
int p = (left + right) / 2;
pivot = railSlope_Vecdata_S.at(p);
//2.分别使用左右两边的元素与基准值比较,将小数放左边,将大数放右边
int i = 0, j = 0;
for (i = left, j = right; i < j;) {
//如果坐标元素且小于基准值,使用下一个元素与基准值比较
while(i < p && railSlope_Vecdata_S.at(i)->position().x < pivot->position().x){
i++;
}
//如果左边有元素,但不再小于基准值,则将左边的元素移动到p指向的位置,
//p指向元素原来的位置。
if(i < p){
railSlope_Vecdata_S.at(p) = railSlope_Vecdata_S.at(i);
p = i;
}
//如果右边元素且大于于基准值,使用下一个元素与基准值比较
while(j > p && railSlope_Vecdata_S.at(j)->position().x >= pivot->position().x){
j--;
}
if(j > p){
railSlope_Vecdata_S.at(p) = railSlope_Vecdata_S.at(j);
p = j;
}
}
//3.直到左右两边元素下标重合时,放入基准值元素
railSlope_Vecdata_S.at(p) = pivot;
//printf("%d, %d\n", p, pivot);
//4.分别对左右两边的分组以递归的方式再分组
if (p - left > 1) {
quicksort_Vecdata_S(railSlope_Vecdata_S, left, p - 1);
}
if(right - p > 1){
quicksort_Vecdata_S(railSlope_Vecdata_S, p + 1, right);
}
}
catch(...)
{
AfxMessageBox(_T("unknown CException in quicksort_Vecdata_S")) ;
}
}
// static CString LongToStr(long lVal);
// static CString IntToStr(int nVal);
}; 2、调用时包含该hpp文件
//zhaoanan 调用时包含该hpp文件
#include "AttrTemplateUtil.hpp"
int main(int argc, char *argv[])
{
//按照x的位置从小到大排序
AttrTemplateUtil::sort_Vecdata_S(railAxle_Vecdata_S);
AttrTemplateUtil::sort_Vecdata_S(railAxle_Vecdata_X);
AttrTemplateUtil::quicksort_Vecdata_S(railAxle_Vecdata_S, 0, railAxle_Vecdata_S.size() - 1);
AttrTemplateUtil::quicksort_Vecdata_S(railAxle_Vecdata_X, 0, railAxle_Vecdata_X.size() - 1);
return 0;
}
|