• 多文件编写类模板编译错误问题


    案例

    类头文件(Person.h)

    #pragma once
    template<class T>
    class Person
    {
    public:
    	Person(T age);
    	void show();
    	T age;
    };
    

     类的实现(Person.cpp) 

    #include "Person.h"
    template<class T>
    Person<T>::Person(T age)
    {
    	this->age = age;
    };
    template<class T>
    void Person<T>:: show()
    {
    	cout << "Age:" << age << endl;
    }
    

     主函数(test.cpp)

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include"Person.h"
    using namespace std;
    int main()
    {
    	Person<int>P(10);
    	P.show();
    	getchar();
    	return 0;
    }
    

      编译结果

     

     原因分析

       1.模板的编译机制 

      模板需要两次编译

      第一次编译是在实例化之前:用来分析基本的语法错误,

      第二次编译是在实例化之后,当把这个类型替换之后,判断有没有语法错误.

      编译器在看到模板的定义的时候。并不马上产生代码,仅仅有在看到用到模板时,比方调用了模板函数 或者 定义了类模板的

      对象的时候。编译器才产生特定类型的代码。进行实例化

       2.c++的编译机制

      C++的编译机制是对每一个cpp文件进行单独编译,在单独编译时如果发现一个函数调用,如果在当前文件找不到函数体,则可能在其他cpp文件中实现了此函数的声明.编译器会在函数位置生成符号代替此函数,在最终的链接阶段由链接器来寻找函数体进行链接

       因此,类模板在编译时,无法知道其他cpp文件中对类模板是否有实例化,因此只进行第一步编译,没有进行实例化,而链接器在链接过程中没有找到实例化的类模板与之对应,因此链接失败,编译错误.

    解决方法

      方法一:将主函数中的头文件(.h)改写为(.cpp) 

     

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include"Person.cpp"
    using namespace std;
    int main()
    {
    	Person<int>P(10);
    	P.show();
    	getchar();
    	return 0;
    }
    

      方法二:将类模板的声明与定义写入同一文件中,并将(.cpp)改为(.hpp)便于与其他文件作出区别(推荐使用)

    template<class T>
    class Person
    {
    public:
    	Person(T age);
    	void show();
    	T age;
    };
    
    template<class T>
    Person<T>::Person(T age)
    {
    	this->age = age;
    };
    template<class T>
    void Person<T>:: show()
    {
    	cout << "Age:" << age << endl;
    }
    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include"Person.hpp"
    using namespace std;
    int main()
    {
    	Person<int>P(10);
    	P.show();
    	getchar();
    	return 0;
    }
    

      

  • 相关阅读:
    图的深度遍历
    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

    满汉全席
    2-sat(模板)
    2-sat
    花匠
    维护序列NOI2005
    序列终结者
    杨辉三角
  • 原文地址:https://www.cnblogs.com/qq209049127/p/10720381.html
Copyright © 2020-2023  润新知