C++模板类的编译问题

<转自“软件工匠笔记”:http://linhs.blog.51cto.com/,特别表示感谢,希望更多被C++模板所折磨的人能看到这篇文章,写得很清楚透彻>

 

一般发布C++类的方法是:使用.H文件写类定义,用CPP文件写实现。发布的时候可以把H文件和CPP编译出来的.O文件给客户程序,然后客户端程序来编译和链接类头文件和目标文件。
  虽然也可以发布CPP源文件,但发布.O文件可以更好的维护类的相对独立性,或者是源代码实现不方便让他人看到。
 
  例如,
 
  有类的头文件:
//Rec.h
#ifndef _REC_H_ 
#define _REC_H_ 
 
class Rec 

     
public
  Rec( int a); 
   void show(); 
private
     int m_a; 
}; 
 
 
#endif 
 
  类的实现文件。
 
//Rec.cpp
#include  "Rec.h" 
#include <iostream> 
using namespace std; 

Rec::Rec( int a) 

  m_a = a; 


void Rec::show(){ 
  printf( "item=%d/n",m_a); 

 
  使用类的时候,首先 g++ -c Rec.cpp 生成Rec.o备用。
 
  编写测试程序
 
//test.cpp
#include  "Rec.h" 

void main() 

  Rec a(10); 
  a.show(); 
}
 
  编译测试程序, g++ -o test test.cpp Rec.o
 
  运行得: item=10
 
  如果把Rec类变成模板类,那么编译的方法就不能如此优雅了。
 
  Rect类头文件
 
//Rect.h 
#ifndef _RECT_H_ 
#define _RECT_H_ 

template < class T> 
class RecT{ 
public
  RecT(T t); 
   void show(); 
private
  T m_a; 
}; 

#endif  //! #ifndef _RECT_H_
 
 
  Rect类实现文件:
 
#Rect.cpp
#include  "RecT.h" 
#include <iostream> 
using namespace std; 

template < class T> 
RecT<T>::RecT(T t) 

  m_a = t; 


template < class T> 
void RecT<T>::show(){ 
  cout<< "item="<<m_a<<endl; 
}
 
 
  测试程序:使用模板类,T用int代替
 
#include  "RecT.h" 

void main() 

  RecT< int> a(10); 
  a.show(); 
}
 
  在VS6下,编译出现错误:
 
Compiling... 
Test.cpp 
Linking... 
Test.obj : error LNK2001: unresolved external symbol  "publicvoid __thiscall RecT<int>::show(void)" (?show@?$RecT@H@@QAEXXZ) 
Test.obj : error LNK2001: unresolved external symbol  "public: __thiscall RecT<int>::RecT<int>(int)" (??0?$RecT@H@@QAE@H@Z) 
Debug/TemplateTest.exe : fatal error LNK1120: 2 unresolved externals 
Error executing link.exe. 
 
  错误分析:
   Test.cpp 在编译目标文件是成功的,在链接的时候出现了错误。找不到RecT<int>类的方法。 
   事实上,Rect.cpp无法独立生成目标文件。理由很简单:因为其中的T类型在使用前还未知类型,如何分配内存还无法确定,自然就无法生成目标文件了。
  所以,编译模板类不能分两步走。模板类的实现文件需要和使用类的程序一起编译,编译器知道程序需要使用何种类后才可以编译出相应的类来。
 
  改改测试程序
 
#include  "RecT.cpp" 

void main() 

  RecT< int> a(10); 
  a.show(); 
}
 
 编译通过并成功运行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++模板类的实现机制是通过在编译时进行类型具体化来生成具体的类和对象。模板类本身是抽象的,也就是类型化的,使用时必须进行类型具体化。具体的类是通过将模板类的类型参数替换为具体的类型来生成的。例如,引用\[1\]的代码模板类C是从模板类A派生而来的,通过具体化模板类C<int>,编译器知道了父类A的数据类型是int,从而能够正确地分配内存和启用父类的构造函数。 在具体化模板类时,编译器需要知道模板类的数据类型具体是什么样的,这样才能确定父类所占的内存大小和如何分配内存。因此,只有在数据类型固定的情况下,才能进行模板类的具体化和继承操作。 总结起来,C++模板类的实现机制是通过在编译时进行类型具体化,将抽象的模板类转化为具体的类和对象,以便正确地分配内存和启用父类的构造函数。 #### 引用[.reference_title] - *1* *2* [C++重要知识清单:泛型编程(函数模板和类模板机制)包含模板机制的底层实现原理](https://blog.csdn.net/weixin_39568744/article/details/105950208)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [C++模板的实现机制](https://blog.csdn.net/qq_41306849/article/details/120020140)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值