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;}
阅读全文
1 0
原创粉丝点击