C++ learning-关于 error LNK2019以及error C2244的 解决方案
来源:互联网 发布:2015年网络作家富豪榜 编辑:程序博客网 时间:2024/06/05 14:37
博主在学习数据结构(C++版,邓俊辉)时,发现敲打书上代码报错,其错误类型是error LNK2019以及error C2244:第一个错误表示:使用了无法解析的外部符号,说明定义和声明没有衔接上,所以=和[]操作符重载失败,因为我是类模板的定义和成员函数定义分别放在h和cpp文件中的,我将报错的函数定义直接移到头文件中,暂时解决了第一个错误。而第二个错误表示:无法将函数定义与现有的声明匹配,但是我仔细检查了定义和匹配是一模一样的,而且我在头文件中是用了#ifndef和#define来防止头文件被重复包含。
博主仔细思考后,感觉是跟模板类的编写规则有关,就回去查阅了c++ primer 讲模板类的部分。发现这个错误是与模板编译类型有关!模板编译类型分为:“包含”模型和“分别编译”模型。因为博主所用的编译器是VS2012,只支持包含模型,重点介绍包含模型来解决上面的问题。解决方案:在类模板的头文件定义类结束后加上#include “模板类名.cpp”,例如:
解决方案1:
// header file Vector.h#ifndef VECTOR_H#define VECTOR_Htemplate <class T> class Vector{//成员和成员函数声明或定义};#include "Vector.cpp" //包含在头文件中只声明的成员函数的定义,一定记得加!#endif
若只是这样,你可能仍然会报错:重复定义或声明某个函数,你还需要做这样的操作:
// Vector.cpp#ifndef VECTOR_CPP#define VECTOR_CPP...//定义那些成员函数#endif
这样解决重复定义问题,你的程序可以重新运行了!
“分别编译”模型:
一句话:就是在cpp文件一开始加上export templateclass 你的类名然后再#include “你的模板类名.h” 成员函数定义…;由于VS2012貌似不支持,所以我也无法演示和验证该方法能否解决问题。。
注意:包含模型的解决方法不适于特化函数和模板函数都放在cpp文件中定义的情况,这种情况下两种办法:1.在特化函数定义加上inline ,将其声明为内联函数。2.使用笨方法,将模板函数定义放于头文件定义中,将特化函数定义放于cpp文件中,具体可参考这篇博客,讲解很详细 。
http://blog.csdn.net/lh844386434/article/details/6713361 。
第一次写博客,不足之处还请指导和见谅!大家觉得有用的请点个赞~
附我的例子代码参考(源于数据结构(C++语言版)第三版):
// Vector.h#ifndef VECTOR_H_#define VECTOR_H_typedef int Rank;#define DEFAULT_CAPACITY 3template <typename T> class Vector{protected : Rank _size; int _capacity; T* _elem; void copyFrom(T const* A,Rank lo,Rank hi); void expand(); void shrink(); bool bubble(Rank lo,Rank hi); void bubbleSort(Rank lo,Rank hi); Rank max(Rank lo,Rank hi); void selectionSort(Rank lo,Rank hi); void merge(Rank lo,Rank mi,Rank hi); void mergeSort(Rank lo,Rank hi); Rank partition(Rank lo,Rank hi); void quickSort(Rank lo,Rank hi); void heapSort(Rank lo, Rank hi);public://构造函数 Vector(int c = DEFAULT_CAPACITY, int s=0,T v=0) { _elem= new T[_capacity=c]; for (_size=0;_size<s;_elem[_size++]=v); } Vector (T const* A,Rank n){ copyFrom(A,0,n); } Vector (T const* A,Rank lo,Rank hi){ copyFrom(A,lo,hi); } Vector (Vector<T> const& V){ copyFrom(V._elem,0,V._size); } Vector (Vector<T> const& V,Rank lo,Rank hi){ copyFrom(V._elem,lo,hi); }//析构函数 ~Vector() { delete [] _elem; }// 只读访问接口 Rank size() const { return _size; } bool empty() const{ return _size; } int disordered() const; Rank find (T const& e) const{ return find(e,0,_size); } Rank find(T const& e,Rank lo,Rank hi ) const; Rank search(T const& e) const{ return (0>=_size)?-1:search(e,0,_size); } Rank search(T const& e,Rank lo,Rank hi) const;//可写访问接口 T& operator[](Rank r) const; Vector<T> & operator=(Vector<T> const&); T remove(Rank r); int remove(Rank lo,Rank hi); Rank insert(Rank r,T const& e); Rank insert(T const& e){ return insert(_size,e); } void sort(Rank lo,Rank hi); void sort(){ sort(0,_size); } void unsort(Rank lo,Rank hi); void unsort(){ unsort(0,_size); } int deduplicate(); int uniquify();//遍历 void traverse(void(*) (T&)); template<typename VST> void traverse(VST&);};#include "Vector.cpp"#endif
// Vector.cpp#ifndef VECTOR_C_#define VECTOR_C_#include "Vector.h"template <typename T> void Vector<T>::copyFrom(T const* A,Rank lo,Rank hi){ _elem=new T[_capacity=2*(hi-lo)]; _size=0; while(lo<hi) _elem[_size++] = A[lo++];}template <typename T> Vector<T>& Vector<T>::operator=(Vector<T> const& V){ if (_elem) delete [] _elem; copyFrom(V._elem,0,V.size()); return *this;}template <typename T>void Vector<T>::expand(){ if (_size< _capacity) return; if (_capacity < DEFAULT_CAPACITY) _capacity=DEFAULT_CAPACITY; T* oldElem= _elem; _elem= new T[_capacity<<1]; for (int i=0;i<_size;i++) _elem[i]=oldElem[i]; delete [] oldElem;}template <typename T> void Vector<T>::shrink(){ if (_capacity<DEFAULT_CAPACITY <<1) return; if (_size <<2 > _capacity) return; T* oleElem=_elem; _elem=new T[_capacity >>1]; for (int i=0;i<_size;i++) _elem[i]=oleElem[i]; delete [] oleElem;}template <typename T> T& Vector<T>::operator[] (Rank r) const{ return _elem[r];}template <typename T> void permute(Vector<T>& V){ for (int i=V.size();i>0;i--) swap(V[i-1],V[rand() % i]);}template <typename T> void Vector<T>::unsort(Rank lo,Rank hi){ T* V=_elem+lo; for (Rank i=hi-lo;i>0;i--) swap(V[i-1],V[rand() % i]);}template <typename T> static bool lt(T* a,T* b){ return lt(*a,*b);}template <typename T> static bool lt(T& a,T& b){ return a<b;}template <typename T> static bool eq(T* a,T* b){ return eq(*a,*b);}template <typename T> static bool eq(T& a,T& b){ return a==b;}template <typename T>Rank Vector<T>::find(T const& e,Rank lo,Rank hi) const{ while ((lo<hi--) && (e!=_elem[hi])); //(0,n),首先执行lo<hi--,则hi=n-1,_elem[hi]正确;当hi=1时,执行完e!=_elem[0]后还是执行一次lo<hi--,则hi=lo-1! return hi;}template <typename T>Rank Vector<T>::insert (Rank r, T const& e){ expand(); for (int i=_size;i>r;i--) _elem[i]=_elem[i-1]; _elem[r]=e; _size++; return r;}template <typename T> int Vector<T>::remove(Rank lo,Rank hi){ if (lo==hi) return 0; while (hi<_size) _elem[lo++]=_elem[hi++]; _size=lo; shrink(); return hi-lo;}template <typename T> T Vector<T>::remove(Rank r){ T e=_elem[r]; remove(r,r+1); return e;}template <typename T> int Vector<T>::deduplicate(){ int oldsize=_size; Rank i=1; while (i<_size) (find(_elem[i],o,i))<0? i++ :remove(i); return oldsize-_size;}template <typename T> void Vector<T>::traverse (void (*visit) (T&)){ for (int i=0;i<_size;i++) visit(_elem[i]);}template <typename T> template <typename VST>void Vector<T>::traverse(VST &visit){ for (int i=0;i<_size;i++) visit(_elem[i]);}template <typename T> struct Increase{ virtual void operator() (T& e){ e++; }};template <typename T> void increase (Vector<T> &V){ V.traverse(Increase<T>());}template <typename T> int Vector<T>::disordered() const{ int n=0; for (int i=1;i<_size;i++) if (_elem[i-1]>_elem[i]) n++; return n;} //n=0有序template <typename T> int Vector<T>::uniquify() { //有序向量重复元素剔除算法(高效版) Rank i=0,j=0; while(++j<_size) if (_elem[i]!=_elem[j]) { _elem[++i]=_elem[j]; } _size=++i; shrink(); return j-i;}//有序查找为search()//template <typename T> static Rank binSearch(T *A,T const& e,Rank lo,Rank hi){ //版本A// while (lo<hi){// Rank mi=(lo+hi)>>1;// if (e<A[mi])// hi=mi;// else if (e>A[mi])// lo=mi;// else// return mi;// }// return -1;//}//template <typename T> static Rank binSearch(T* A,T cosnt& e,Rank lo,Rank hi){ //版本B// while (1<hi-lo){// Rank mi=(lo+hi)>>1;// (e<A[mi])?hi=mi:lo=mi;// }// return (e==A[lo])?lo:-1;//}template <typename T> static Rank binSearch(T* A,T const& e,Rank lo,Rank hi){ //版本C,返回小于等于e的秩最大者 while (lo<hi){ Rank mi=(lo+hi)>>1; (e<A[mi])?hi=mi:lo=mi+1; } return --lo;}#include "Fib.h" //自己编写Fib.htemplate <typename T> static Rank fibSearch(T* A,T const& e,Rank lo,Rank hi){ Fib fib(hi-lo); while (lo<hi){ while (hi-lo<fib.get()) fib.prev(); Rank mi=lo+fib.get()-1; if (e<A[mi]) hi=mi; else if (e>A[mi]) lo=mi; else return mi; } return -1;}template <typename T>Rank Vector<T>::search(T const& e,Rank lo,Rank hi) const{ return (rand() % 2)? binSearch(_elem,e,lo,hi):fibSearch(_elem,e,lo,hi);}template <typename T> void Vector<T>::sort (Rank lo,Rank hi){ switch (rand()%5) { case 1: case 2:bubbleSort(lo,hi);break; case 3: case 4:mergeSort(lo,hi);break; default: mergeSort(lo,hi);break; break; }}template<typename T> bool Vector<T>::bubble(Rank lo,Rank hi){ bool sorted=true; while(++lo<hi) { if (_elem[lo-1]>_elem[lo]){ sorted=false; swap(_elem[lo-1],_elem[lo]); } } return sorted;}template <typename T> void Vector<T>::bubbleSort(Rank lo,Rank hi){ while(!bubble(lo,hi--)) ;}template<typename T> void Vector<T>::merge(Rank lo,Rank mi,Rank hi){ T* A=_elem+lo; int lb=mi-lo; T *B=new T[lb]; for (Rank i=0;i<lb;B[i]=A[i++]); int lc=hi-mi; T* C=_elem+mi; for (Rank i=0,j=0,k=0;(j<lb) ||(k<lc);){ if ((j<lb) && (!(k<lc) || B[j]<=C[k])) A[i++] =B[j++]; if ((k<lc) && (!(j<lb) || C[k]<B[j])) A[i++]=C[k++]; } delete [] B;}template <typename T> void Vector<T>::mergeSort(Rank lo,Rank hi){ if (hi-lo <2) return; int mi=(hi+lo)/2; mergeSort(lo,mi); mergeSort(mi,hi); merge(lo,mi,hi);}#endif
// main.cpp 测试Vector部分功能#include <iostream>#include "Vector.h"#include "Fib.h"using namespace std;int main(int argc,char* argv[]){ const int a[]={1,3,4,7,2,5,9,6,8}; Vector<int> v1(a,9),v2; v2=v1; cout<<"v1: "; permute(v1); for (int i=0;i<v1.size();i++) cout<<v1[i]<<" "; cout<<endl; cout<<"v2: "; for (int i=0;i<v2.size();i++) cout<<v2[i]<<" "; cout<<endl; int flag=v2.find(5,0,9); cout<<flag<<endl; v2.insert(4,10); cout<<"v2: "; for (int i=0;i<v2.size();i++) cout<<v2[i]<<" "; cout<<endl; v2.remove(4,5); cout<<"v2: "; for (int i=0;i<v2.size();i++) cout<<v2[i]<<" "; cout<<endl; v1.sort(0,9); cout<<"v1: "; for (int i=0;i<v1.size();i++) cout<<v1[i]<<" "; cout<<endl; return 0;}
- C++ learning-关于 error LNK2019以及error C2244的 解决方案
- 关于error LNK2019
- 关于 VS2008 error LNK2019错误的解决方法
- [C++] 烦人的error LNK2019和error LNK2001
- error LNK2019的解决方法
- “error LNK2019” 的解决方法
- “error LNK2019:无法解析的外部符号”的解决方案
- error LNK2019:unresolved external symbol *** referenced in function ***的解决方案
- error LNK2019:unresolved external symbol *** referenced in function ***的解决方案
- error LNK2019:unresolved external symbol *** referenced in function ***的解决方案
- error LNK2019:unresolved external symbol *** referenced in function ***的解决方案
- error LNK2019:unresolved external symbol *** referenced in function ***的解决方案
- VS2010 error lnk2019 的一个解决方案 环境变量设置
- error LNK2019:unresolved external symbol *** referenced in function ***的解决方案
- C++ error LNK2019: 无法解析的外部符号 错误解决方案
- VS error LNK2019: 无法解析的外部符号 解决方案之一
- ERROR LNK2019
- error LNK2019
- Oracle 11g RAC 补丁升级时报ORA-01565: error in identifying spfileprod.ora 错误处理
- 算法概论
- MarkDown语法
- 第二章 SQL命令参考-ROLLBACK TO SAVEPOINT
- 排序算法总结
- C++ learning-关于 error LNK2019以及error C2244的 解决方案
- centos7.0忘记root密码
- 什么是单点登录SSO(Single Sign-On)?
- PX4源码学习一--Pix和APM的区别
- 17.11.14日报
- 46. Permutations, 47. Permutations II
- 输出菱形
- 深入了解JVM、JRE、JDK 什么是JVM、JRE、JDK
- 6.4