【模板代码的组织结构与模板的显式实例化和声明】模板代码的组织结构与模板 ...

打印 上一主题 下一主题

主题 641|帖子 641|积分 1923

一、模板的组织结构

之前对于模板,我们都是写在同一个                                   .                         c                         p                         p                              .cpp                  .cpp文件下,那如果我们将模板分开,单独开一个                                   .                         h                              .h                  .h和                                   .                         c                         p                         p                              .cpp                  .cpp来创建模板,会发生什么?
首先,我们创建一个                                   m                         y                         c                         l                         a                         s                         s                         .                         h                              myclass.h                  myclass.h文件,写入以下代码:
  1. #ifndef __MYCLASS_H__
  2. #define __MYCLASS_H__
  3. #include<iostream>
  4. template<typename T>
  5. class MYClass {
  6. public :
  7.         void func();
  8. };
  9. #endif
复制代码
注意这里的代码是防止多次引用头文件
  1. #ifndef __MYCLASS_H__
  2. #define __MYCLASS_H__
复制代码
然后我们创建一个                                   m                         y                         c                         l                         a                         s                         s                         .                         c                         p                         p                              myclass.cpp                  myclass.cpp文件,类外实现一下模板
  1. template<typename T>
  2. void MYClass<T>::func() {
  3.         std::cout << "MYClass::func成员函数执行了\n";
  4. }
复制代码
然后再主函数                                   m                         a                         i                         n                         .                         c                         p                         p                              main.cpp                  main.cpp内写入:
  1. #include "myclass.h"
  2. int main() {
  3.         MYClass<int> myc;
  4.         myc.func();
  5.         return 0;
  6. }
复制代码
看上去没什么题目,编译器也没有报错,我们运行一下:

显然,这里链接失败了,缘故原由如下:
编译器首先在                                        m                            a                            i                            n                            .                            c                            p                            p                                  main.cpp                     main.cpp中实行实例化出                                        M                            Y                            C                            l                            a                            s                            s                            <                            i                            n                            t                            >                                  MYClass<int>                     MYClass<int>这个类,由于在当前编译单元找不到                                        M                            Y                            C                            l                            a                            s                            s                                  MYClass                     MYClass类模板的实现,编译器不会因此报错,而是假设在别的编译单元已经实例化出了这个类。但是链接的时候发现别的编译单元也没有实例化出这个类,因此就会发生链接错误。
因此,解决方法就是在                                   m                         y                         c                         l                         a                         s                         s                         .                         h                              myclass.h                  myclass.h文件中就完成模板的实现,这样在引用头文件的时候就不会由于编译器的忽略而发生链接错误了:
  1. template<typename T>class MYClass {public:        void func() ;};//直接再.h文件内实现template<typename T>
  2. void MYClass<T>::func() {
  3.         std::cout << "MYClass::func成员函数执行了\n";
  4. }
复制代码
编译运行:

二、模板的显式实例化、模板声明、代码组织结构

如果多个                                   .                         c                         p                         p                              .cpp                  .cpp文件调用同一个模板,可能会实例化出多个相同的实例模板,我们可以通过对模板的显式实例化和声明来制止多次实例化。
我们加入                                   c                         a                         .                         h                              ca.h                  ca.h,在里面界说一些模板
  1. #ifndef __CAH__
  2. #define __CAH__
  3. #include<iostream>
  4. template<typename C>
  5. class A {
  6. public:
  7.         //成员函数模板
  8.         template<typename T2>
  9.         A(T2 v1, T2 v2);
  10.         template<typename T>
  11.         void myft(T tmpt) {
  12.                 std::cout << tmpt << "\n";
  13.         }
  14.        
  15.         C m_ic;
  16. };
  17. //类外实现构造函数
  18. template<typename T>
  19. template<typename T2>
  20. A<T>::A(T2 v1,T2 v2) {
  21.         std::cout << v1 << " " << v2 << "\n";
  22. }
  23. //定义一个函数模板
  24. template<typename T>
  25. void myfunc(T v1, T v2) {
  26.         std::cout << v1 + v2 << "\n";
  27. }
  28. #endif
复制代码
这里有构造函数模板和成员函数模板。
然后我们在                                   t                         e                         s                         t                         .                         c                         p                         p                              test.cpp                  test.cpp和                                   m                         a                         i                         n                         .                         c                         p                         p                              main.cpp                  main.cpp中调用这些模板:
                                    t                         e                         s                         t                         .                         c                         p                         p                              test.cpp                  test.cpp:
  1. #include "ca.h"
  2. void myfunc() {
  3.         A<float>a(1, 2);
  4.         a.myft(3);
  5.         myfunc(1, 2);
  6. }
复制代码
                                   m                         a                         i                         n                         .                         c                         p                         p                              main.cpp                  main.cpp:
  1. #include "ca.h"
  2. int main() {
  3.        
  4.         A<float>a(1, 2);
  5.         A<float>a2(1.1, 2.2);
  6.         a.myft(3);
  7.         myfunc(1, 2);
  8.         return 0;
  9. }
复制代码
这样我们会实例化出多个                                   A                         <                         f                         l                         o                         a                         t                         >                              A<float>                  A<float>和                                   m                         y                         f                         u                         n                         c                         (                         )                              myfunc()                  myfunc()函数,那么我们可以通过模板声明和显式实例化来制止:
在                                   t                         e                         s                         t                         .                         c                         p                         p                              test.cpp                  test.cpp和                                   m                         a                         i                         n                         .                         c                         p                         p                              main.cpp                  main.cpp进行更改:


加入以上的内容,注意,实例化声明可以有多个,而实例化界说只能有一个,且必须在界说后才气声明。
这样我们实例化出的模板只会有一个,然后通过在链接的时候就会在别的                                   .                         c                         p                         p                              .cpp                  .cpp文件中找到这个界说。
注意的是,这样的显式实例化界说,如                                        t                            e                            m                            p                            l                            a                            t                            e                            A                            <                            f                            l                            o                            a                            t                            >                                  template A<float>                     templateA<float>,会将类                                        A                                  A                     A中所有的内容都实例化出来,这样也会带来额外的开销。
总之,对于实例化界说和声明有其优秀的一面,也有其欠好的一面,要看现实环境来选择具体的方法。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81428

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表