c/c++语言开发共享C++中的数据类模板

1,预备知识: 1,模板参数可以是数值型参数(非类型参数): 1,代码示例: 2,数值型模板参数的限制: 1,变量不能作为模板参数; 1,是变量的话就不满足准确确定的这个本质; 2,浮点数不能作为模板参数; 1,浮点数本身不精确; 3,类对象不能作为模板参数; 1,类对象编译时不能唯一确定的,同变量 …

1,预备知识:

    1,模板参数可以是数值型参数(非类型参数):

       1,代码示例:

1 template <typename t, int n>   2 void func()  3 {  4     t a[n];  // 使用模板参数定义局部数组;  5 }  6              7 func<double, 10>();  // 使用模板时,数值型参数必须是常量,不能是变量;

    2,数值型模板参数的限制:

       1,变量不能作为模板参数;

           1,是变量的话就不满足准确确定的这个本质;

       2,浮点数不能作为模板参数;

           1,浮点数本身不精确;

       3,类对象不能作为模板参数;

           1,类对象编译时不能唯一确定的,同变量一样;

    3,数值型参数本质:模板参数是在编译阶段被处理的单元,因此,在编译阶段必须准确无误的唯一确定;

          

2,有趣的面试题:

    1,用你觉得最高效的方法求 1 + 2 + 3 + … + n 的值;

       1,等差数列和的方式;

       2,见下面实例;

   

3,数值型模板参数编程实验:

 1 #include <iostream>   2 #include <string>   3    4 using namespace std;   5    6 /* 验证上面的预备知识 */   7 template   8 < typename t, int n >  // 这里用成 double 后,编译器显示:error: 'double' is not a valid type for a template constant parameter   9 void func()  10 {  11     t a[n] = {0};  12       13     for(int i=0; i<n; i++)  14     {  15         a[i] = i;  16     }  17       18     for(int i=0; i<n; i++)  19     {  20         cout << a[i] << endl;  21     }  22 }  23   24 /* 用最高效的方法验证从 1 加到 n 的和;不用循环和等差数列求和公式 */  25 template  26 < int n >  27 class sum  28 {  29 public:  30     // static const int value = 0;  // static 后是想定义常量,被 static 修饰后要么放入符号表、要么放到全局数据区; 这个时候 value 已经确定了值,所以直接进入符号表(符号表存储在哪里呢);又因为 value 被 static 修饰了,所以 value 被放入全局数据区;  31     static const int value = sum<n-1>::value + n;  // 递归定义  32 };  33   34 /* 定义上述模板类的特化实现,实现递归出口 */  35 template  36 < >  37 class sum < 1 >  38 {  39 public:  40     static const int value = 1;  41 };  42   43 int main()  44 {  45     func<int, 10>();  // 打印 0 到 9 这十个数字;这里如果模板参数类型为 double,编译器显示:error: no matching function for call to 'func()';  46       47     int a = 10;  48     func<int, a>();  // 在这一行编译器显示:  49        // error: 'a' cannot appear in a constant-expression  50        // error: no matching function for call to 'func()'  51                        52     cout << "1 + 2 + 3 + ... + 10 = " << sum<10>::value << endl;  // 55;这里没有加减乘除法,也没有函数调用和循环,这里value 是常量,并在编译的时候已经确定,这里效率是最高的;  53     cout << "1 + 2 + 3 + ... + 100 = " << sum<100>::value << endl;   // 5050  54       55     return 0;  56 }    

    1,这里的相加求和是在编译器编译程序的时候完成的,编译完程序后,要求的和的值已经确定,在运行的时候,就直接可以访问这个值,不需要做任何的运算和循环,因此效率最高;

    2,这个最高效的求和依赖了模板技术、模板特化技术、数值型模板参数技术;

    3,可以举一反三,得到更多高效的程序写法;

   

4,数组模板类编程实验:

    1,array.h 文件:

 1 #ifndef _array_h_  // 防止多次包含头文件;   2 #define _array_h_   3    4 template   5 < typename t, int n >  // 数组元素的类型和大小;   6 class array   7 {   8     t m_array[n];  // 定义一个实际的数组;   9 public:  10     int length();  11     bool set(int index, t value);  12     bool get(int index, t& value);  13     t& operator[] (int index);  14     t operator[] (int index) const;  // 数组类对象有可能是 const 对象,这个时候就只能调用 const 函数,所以要定义这个;const 函数只能返回值,不能返回引用;  15     virtual ~array();  // 有可能被继承  16 };  17   18 /* 模板类要放在一个文件中,所以实现在下面实现 */  19   20 template  21 < typename t, int n >  22 int array<t, n>::length()  23 {  24     return n;  25 }  26   27 template  28 < typename t, int n >  29 bool array<t, n>::set(int index, t value)  30 {  31     bool ret = (0 <= index) && (index < n);  32       33     if( ret )  34     {  35         m_array[index] = value;  36     }  37       38     return ret;  39 }  40   41 template  42 < typename t, int n >  43 bool array<t, n>::get(int index, t& value)  44 {  45     bool ret = (0 <= index) && (index < n);  46       47     if( ret )  48     {  49         value = m_array[index];  50     }  51       52     return ret;  53 }  54   55 template  56 < typename t, int n >  57 t& array<t, n>::operator[] (int index)  58 {  59     return m_array[index];  60 }  61   62 template  63 < typename t, int n >  64 t array<t, n>::operator[] (int index) const  65 {  66     return m_array[index];  67 }  68   69 template  70 < typename t, int n >  71 array<t, n>::~array()  72 {  73   74 }  75   76 #endif

    2,应用:

 1 #include <iostream>   2 #include <string>   3 #include "array.h"   4    5 using namespace std;   6    7 int main()   8 {   9     array<double, 5> ad;  10       11     for(int i=0; i<ad.length(); i++)  12     {  13         ad[i] = i * i;  14     }  15       16     for(int i=0; i<ad.length(); i++)  17     {  18         cout << ad[i] << endl;  19     }  20       21     return 0;  22 }

   

5,堆数组模板类编程实验:

 1,heaparray.h 文件:

  1 #ifndef _heaparray_h_    2 #define _heaparray_h_    3     4 template    5 < typename t >    6 class heaparray    7 {    8 private:    9     int m_length;   10     t* m_pointer;   11        12     heaparray(int len);   13     heaparray(const heaparray<t>& obj);   14     bool construct();   15 public:   16     static heaparray<t>* newinstance(int length);    17     int length();   18     bool get(int index, t& value);   19     bool set(int index ,t value);   20     t& operator [] (int index);   21     t operator [] (int index) const;  // 有可能有 const 对象;   22     heaparray<t>& self();   23     ~heaparray();  // 这个时候构造函数是 private 的,也就是 heaparray 类不希望被继承,所以说没有必要将它声明为 virtual 的;   24 };   25    26 /* 实现要在同一个文件中 */   27    28 template   29 < typename t >   30 heaparray<t>::heaparray(int len)   31 {   32     m_length = len;   33 }   34    35 template   36 < typename t >   37 bool heaparray<t>::construct()   38 {      39     m_pointer = new t[m_length];   40        41     return m_pointer != null;   42 }   43    44 template   45 < typename t >   46 heaparray<t>* heaparray<t>::newinstance(int length)    47 {   48     heaparray<t>* ret = new heaparray<t>(length);   49        50     if( !(ret && ret->construct()) )    51     {   52         delete ret;   53         ret = 0;   54     }   55            56     return ret;   57 }   58    59 template   60 < typename t >   61 int heaparray<t>::length()   62 {   63     return m_length;   64 }   65    66 template   67 < typename t >   68 bool heaparray<t>::get(int index, t& value)   69 {   70     bool ret = (0 <= index) && (index < length());   71        72     if( ret )   73     {   74         value = m_pointer[index];   75     }   76        77     return ret;   78 }   79    80 template   81 < typename t >   82 bool heaparray<t>::set(int index, t value)   83 {   84     bool ret = (0 <= index) && (index < length());   85        86     if( ret )   87     {   88         m_pointer[index] = value;   89     }   90        91     return ret;   92 }   93    94 template   95 < typename t >   96 t& heaparray<t>::operator [] (int index)   97 {   98     return m_pointer[index];   99 }  100   101 template  102 < typename t >  103 t heaparray<t>::operator [] (int index) const  104 {  105     return m_pointer[index];  106 }  107   108 template  109 < typename t >  110 heaparray<t>& heaparray<t>::self()  111 {  112     return *this;  113 }  114   115 template  116 < typename t >  117 heaparray<t>::~heaparray()  118 {  119     delete[]m_pointer;  120 }  121   122 #endif

    2,应用:

 1 #include <iostream>   2 #include <string>   3 #include "heaparray.h"   4    5 using namespace std;   6    7 int main()   8 {      9     heaparray<char>* pai = heaparray<char>::newinstance(10);  10       11     if( pai != null )  12     {  13         heaparray<char>& ai = pai->self();  14           15         for(int i=0; i<ai.length(); i++)  16         {  17             ai[i] = i + 'a';  18         }  19           20         for(int i=0; i<ai.length(); i++)  21         {  22             cout << ai[i] << endl;  23         }  24     }  25       26     delete pai;  27       28     return 0;  29 }

   

6,小结:

    1,模板参数可以是数值型参数;

    2,数值型模板参数必须在编译期间唯一确定;

    3,数组类模板是基于数值型模板参数实现的;

    4,数组类模板是简易的线性表数据结构;

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/603316.html

(0)
上一篇 2021年5月11日
下一篇 2021年5月11日

精彩推荐