关于VS中LNK1120与errorLNK2019问题

      最近遇到了该问题,再查找了一些资料后,发现了针对自己问题的解决方法,贴出来让大家一起学习一下。

  其实如果这两个问题同时出现,很可能不是链接库缺了lib,而是编译中添加的源没有被实例化,造成编译时,机器以为是缺失lib。本人用的编译器为vs2012,问题出在与,在.h声明了函数后,在.hpp下进行了定义。问题在于.hpp不是其源文件。所以最后生成LNK错误。以前自己移动过,再次添加源文件没注意,造成了.hpp没有被认为是源文件而是头文件。

   下面是我看到的一个例子,分享一下。

摘自[1].http://q.cnblogs.com/q/34032/

  我在一个头文件里定义了声明了一个模版函数,如下:

//Combination.h
#ifndef VECTOR_H
#define VECTOR_H

#include 

#endif

template void Combination(T a[], int len, int index, int m, std::vector& c);
CPP里定义

//Combination.cpp
#include "Combination.h"

using namespace std; 

template void Combination(T a[], int len, int index, int m, vector& c)
{
    if(0 == m)
    {
        vector::iterator iter = c.begin();
        for(; iter != c.end(); ++iter)
        {
            cout<<*iter;
        }
        printf("\n");
        return;
    }

    if(len == index)
        return;

    c.push_back(a[index]);
    Combination(a, len, index + 1, m - 1, c);
    c.pop_back();

    Combination(a, len, index + 1, m, c); 
}

main中调用

#include 
#include "Combination.h"

#ifndef VECTOR_H
#define VECTOR_H

#include 

#endif

using namespace std;

void main()
{
    int a[] = {1,2,3,4,5,6};
    
    vector c;
    Combination(a, sizeof(a) / sizeof(int), 0, 3, c);
        
    system("pause");
    return;
}

编译连接时提示以下错误

错误 1 error LNK2019: 无法解析的外部符号 "void __cdecl Combination(int * const,int,int,int,class std::vector > &)" (??$Combination@H@@YAXQAHHHHAAV?$vector@HV?$allocator@H@std@@@std@@@Z),该符号在函数 _main 中被引用 main.obj CppTest
错误 2 fatal error LNK1120: 1 个无法解析的外部命令 D:\Documents\Visual Studio 2008\Projects\CppTest\Debug\CppTest.exe CppTest

解决方法:

   把方法或类定义放到声明的.h文件中去。

      理解这个问题,需要一点编译原理的知识,在调用一个方法或者使用一个类的时候,本cpp作为一个独立的编译单元,可能并不知道某一个方法或者类型的符号是怎么样的,但是这时候不会出错,还是可以针对每个编译单元生成目标文件obj,之后针对没有找到的方法或者类型符号,链接器会在别的obj文件中寻找缺失的符号。

   假设模版函数可以放在头文件中声明,CPP中定义,按照你的例子分析一下:
main中调用Combination(a, sizeof(a) / sizeof(int), 0, 3, c);,也就是类型Combination(int, int,int,int, vector&);但是编译器并不知道Combination(int, int,int,int, vector&);,因为这个类型并不在任何一个.h文件中,之后编译器会寄希望于链接器可以解决这个问题,也就是在Combination.cpp的编译目标文件Combination.obj中,但是Combination.obj也没有这个类型,它有的只是一个模板定义。


C++标准里规定: 当一个模板不被用到的时侯它就不该被实例化出来,Combination.cpp没有用到Combination(int, int,int,int, vector&);,所以也就不会编译出来该符号,链接出错也就可以理解了。



  

你可能感兴趣的:(c++)