zoukankan      html  css  js  c++  java
  • 多文件编写类模板编译错误问题

    案例

    类头文件(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;
    }
    

      

  • 相关阅读:
    poj 3693 Maximum repetition substring 重复次数最多的连续子串
    hdu 3518 Boring counting 后缀数组 height分组
    Codeforces 920G List Of Integers 二分 + 容斥
    Codeforces 920E Connected Components? 补图连通块个数
    Codeforces 920D Tanks
    LeetCode Weekly Contest 70 A B C D
    Educational Codeforces Round 37 A B C D E F
    检查站点SSL证书配置是否正确
    nginx rewrite之后post参数丢失问题
    Linux中如何避免buffers/cached占用过多内存
  • 原文地址:https://www.cnblogs.com/qq209049127/p/10720381.html
Copyright © 2011-2022 走看看