• 类模板无法解析的外部符号


    如果将类模板的声明和实现写在两个独立的文件中,在构建时会出现“error LNK2019: 无法解析的外部符号 ”的错误。

    现象:当单独编译每个.cpp文件时,都可以编译过,但是当程序运行时,也就是链接时就报“无法解析的外部符号 ”的错误

    原因:链接时,没有找到函数的实现部分,这个跟函数模板实现机制和C++编译机制有关,C++每个cpp单独编译 ,.h文件不编译,  比如下面的例子,有MyClass.cpp和Main.cpp,当编译Main.cpp时,发现MyClass<int, int> class1(3, 5) 和class1.Show()这两个函数调用,此时先编译过,先生成2个函数符号,当链接的时候去找这2个函数的实现部分。然后编译MyClass.cpp时,发现有2个模板函数,但是此时编译不会生成具体的函数,只有模板函数在调用的时候才生成具体的函数,所以也编译后,但是其实没有2个函数的具体实现部分,所以链接时找不到。

    实例:

     MyClass.h:

    #ifndef _CLASS_TEMPLATE_H_
    #define _CLASS_TEMPLATE_H_
    
    template<typename T1, typename T2>
    class MyClass
    {
    public:
        MyClass(T1 tOne, T2 tTwo);//Constructor
        void Show();
    
    private:
        T1 mOne;
        T2 mTwo;
    };
    #endif

    MyClass.cpp:

    #include "MyClass.h"
    #include <iostream>
    using namespace std;
    
    template <typename T1, typename T2>
    MyClass<T1, T2>::MyClass(T1 tOne, T2 tTwo)
    {
      mOne = tOne;
       mTwo = tTwo;
    } template
    <typename T1, typename T2> void MyClass<T1, T2>::Show() { cout << "mOne=" << mOne << ", mTwo=" << mTwo << endl; }

    Main.cpp

    #include<iostream>
    #include "MyClass.h"
    using namespace std;
    
    int main()
    {
        MyClass<int, int> class1(3, 5);
        class1.Show();
    
        system("pause");
        return 0;
    }

    这样写会报错:

     解决办法:

    办法1:将函数实现和函数声明合并在一起,即将MyClass.cpp和MyClass.h相合并,即直接写为MyClass.h,去掉MyClass.cpp文件,如下

    MyClass.h

    #ifndef _CLASS_TEMPLATE_H_
    #define _CLASS_TEMPLATE_H_
    
    template<typename T1, typename T2>
    class MyClass
    {
    public:
        MyClass(T1 tOne, T2 tTwo)
        {
            mOne = tOne;
            mTwo = tTwo;
        }
        void Show()
        {
            cout << "mOne=" << mOne << ", mTwo=" << mTwo << endl;
        }
    
    private:
        T1 mOne;
        T2 mTwo;
    };
    #endif

    Main.cpp:

    #include<iostream>
    #include "MyClass.h"
    using namespace std;
    
    int main()
    {
        MyClass<int, int> class1(3, 5);
        class1.Show();
    
        system("pause");
        return 0;
    }

     办法2:还是包含Main.cpp,Main.h和Main.cpp,但是Main.cpp里面的#include "MyClass.h"换成#include "MyClass.cpp",

    注意:一般情况下写类模板时,没有.h和.cpp文件,是创建一个命名为  ***.hpp的文件,并将声明和实现同时写在里面,其他地方调用时添加#include "  ***.hpp  "。 

    111
  • 相关阅读:
    2.(两个单链表 加法运算)ADD TWO Numbers
    1.从一串数字中找到相加等于target的两个数。TWO SUM
    idea自动注入和自动编译
    idea安装plugin
    idea刷新项目、清除项目缓存
    idea配置jdk
    负载均衡,会话保持,session同步(转)
    【Spring源码分析】Bean加载流程概览
    Maven使用--基本入门
    Git使用:
  • 原文地址:https://www.cnblogs.com/zwj-199306231519/p/12989829.html
Copyright © 2020-2023  润新知