1,预备知识:

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

1,代码示例:

 template <typename T, int N>
void func()
{
T a[N]; // 使用模板参数定义局部数组;
} func<double, >(); // 使用模板时,数值型参数必须是常量,不能是变量;

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

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

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

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

1,浮点数本身不精确;

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

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

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

2,有趣的面试题:

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

1,等差数列和的方式;

2,见下面实例;

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

 #include <iostream>
#include <string> using namespace std; /* 验证上面的预备知识 */
template
< typename T, int N > // 这里用成 double 后,编译器显示:error: 'double' is not a valid type for a template constant parameter
void func()
{
T a[N] = {}; for(int i=; i<N; i++)
{
a[i] = i;
} for(int i=; i<N; i++)
{
cout << a[i] << endl;
}
} /* 用最高效的方法验证从 1 加到 n 的和;不用循环和等差数列求和公式 */
template
< int N >
class Sum
{
public:
// static const int VALUE = 0; // static 后是想定义常量,被 static 修饰后要么放入符号表、要么放到全局数据区; 这个时候 VALUE 已经确定了值,所以直接进入符号表(符号表存储在哪里呢);又因为 VALUE 被 static 修饰了,所以 VALUE 被放入全局数据区;
static const int VALUE = Sum<N->::VALUE + N; // 递归定义
}; /* 定义上述模板类的特化实现,实现递归出口 */
template
< >
class Sum < >
{
public:
static const int VALUE = ;
}; int main()
{
func<int, >(); // 打印 0 到 9 这十个数字;这里如果模板参数类型为 double,编译器显示:error: no matching function for call to 'func()'; int a = ;
func<int, a>(); // 在这一行编译器显示:
// error: 'a' cannot appear in a constant-expression
// error: no matching function for call to 'func()' cout << "1 + 2 + 3 + ... + 10 = " << Sum<>::VALUE << endl; // 55;这里没有加减乘除法,也没有函数调用和循环,这里VALUE 是常量,并在编译的时候已经确定,这里效率是最高的;
cout << "1 + 2 + 3 + ... + 100 = " << Sum<>::VALUE << endl; // return ;
}

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

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

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

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

1,Array.h 文件:

 #ifndef _ARRAY_H_  // 防止多次包含头文件;
#define _ARRAY_H_ template
< typename T, int N > // 数组元素的类型和大小;
class Array
{
T m_array[N]; // 定义一个实际的数组;
public:
int length();
bool set(int index, T value);
bool get(int index, T& value);
T& operator[] (int index);
T operator[] (int index) const; // 数组类对象有可能是 const 对象,这个时候就只能调用 const 函数,所以要定义这个;const 函数只能返回值,不能返回引用;
virtual ~Array(); // 有可能被继承
}; /* 模板类要放在一个文件中,所以实现在下面实现 */ template
< typename T, int N >
int Array<T, N>::length()
{
return N;
} template
< typename T, int N >
bool Array<T, N>::set(int index, T value)
{
bool ret = ( <= index) && (index < N); if( ret )
{
m_array[index] = value;
} return ret;
} template
< typename T, int N >
bool Array<T, N>::get(int index, T& value)
{
bool ret = ( <= index) && (index < N); if( ret )
{
value = m_array[index];
} return ret;
} template
< typename T, int N >
T& Array<T, N>::operator[] (int index)
{
return m_array[index];
} template
< typename T, int N >
T Array<T, N>::operator[] (int index) const
{
return m_array[index];
} template
< typename T, int N >
Array<T, N>::~Array()
{ } #endif

2,应用:

 #include <iostream>
#include <string>
#include "Array.h" using namespace std; int main()
{
Array<double, > ad; for(int i=; i<ad.length(); i++)
{
ad[i] = i * i;
} for(int i=; i<ad.length(); i++)
{
cout << ad[i] << endl;
} return ;
}

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

 1,HeapArray.h 文件:

 #ifndef _HEAPARRAY_H_
#define _HEAPARRAY_H_ template
< typename T >
class HeapArray
{
private:
int m_length;
T* m_pointer; HeapArray(int len);
HeapArray(const HeapArray<T>& obj);
bool construct();
public:
static HeapArray<T>* NewInstance(int length);
int length();
bool get(int index, T& value);
bool set(int index ,T value);
T& operator [] (int index);
T operator [] (int index) const; // 有可能有 const 对象;
HeapArray<T>& self();
~HeapArray(); // 这个时候构造函数是 private 的,也就是 HeapArray 类不希望被继承,所以说没有必要将它声明为 virtual 的;
}; /* 实现要在同一个文件中 */ template
< typename T >
HeapArray<T>::HeapArray(int len)
{
m_length = len;
} template
< typename T >
bool HeapArray<T>::construct()
{
m_pointer = new T[m_length]; return m_pointer != NULL;
} template
< typename T >
HeapArray<T>* HeapArray<T>::NewInstance(int length)
{
HeapArray<T>* ret = new HeapArray<T>(length); if( !(ret && ret->construct()) )
{
delete ret;
ret = ;
} return ret;
} template
< typename T >
int HeapArray<T>::length()
{
return m_length;
} template
< typename T >
bool HeapArray<T>::get(int index, T& value)
{
bool ret = ( <= index) && (index < length()); if( ret )
{
value = m_pointer[index];
} return ret;
} template
< typename T >
bool HeapArray<T>::set(int index, T value)
{
bool ret = ( <= index) && (index < length()); if( ret )
{
m_pointer[index] = value;
} return ret;
} template
< typename T >
T& HeapArray<T>::operator [] (int index)
{
return m_pointer[index];
} template
< typename T >
T HeapArray<T>::operator [] (int index) const
{
return m_pointer[index];
} template
< typename T >
HeapArray<T>& HeapArray<T>::self()
{
return *this;
} template
< typename T >
HeapArray<T>::~HeapArray()
{
delete[]m_pointer;
} #endif

2,应用:

 #include <iostream>
#include <string>
#include "HeapArray.h" using namespace std; int main()
{
HeapArray<char>* pai = HeapArray<char>::NewInstance(); if( pai != NULL )
{
HeapArray<char>& ai = pai->self(); for(int i=; i<ai.length(); i++)
{
ai[i] = i + 'a';
} for(int i=; i<ai.length(); i++)
{
cout << ai[i] << endl;
}
} delete pai; return ;
}

6,小结:

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

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

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

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

C++中的数据类模板的更多相关文章

  1. Sql Server中的数据类型和Mysql中的数据类型的对应关系(转)

    Sql Server中的数据类型和Mysql中的数据类型的对应关系(转):https://blog.csdn.net/lilong329329/article/details/78899477 一.S ...

  2. Xcode6中如何使用自定义的类模板

    说到IOS类的模板,有些人感觉很陌生,但是只要有开发过IOS程序的人,其实都用过类的模板,只不过是用的系统自带的类的模板. 例如创建一个ClassTemplateVC继承于UIViewControll ...

  3. 04737_C++程序设计_第7章_类模板与向量

    例7.1 使用类模板的实例. 例7.2 求4个数中最大值的类模板程序. #include <iostream> using namespace std; template <clas ...

  4. C++_进阶之函数模板_类模板

     C++_进阶之函数模板_类模板 第一部分 前言 c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来 ...

  5. C++复习:函数模板和类模板

    前言 C++提供了函数模板(function template).所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表.这个通用函数就称为函数模板.凡是函数体 ...

  6. C++解析(26):函数模板与类模板

    0.目录 1.函数模板 1.1 函数模板与泛型编程 1.2 多参数函数模板 1.3 函数重载遇上函数模板 2.类模板 2.1 类模板 2.2 多参数类模板与特化 2.3 特化的深度分析 3.小结 1. ...

  7. 4.1 pair类模板

    在学习关联容器之前,首先先要了解一下STL中的pair类模板,因为关联容器的一些成员函数返回值都是pair对象,而且map 和multimap中的元素都是pair对象. 1)pair类模板定义 pai ...

  8. 类模板的困扰 LNK2019 (转)

    原文地址:http://www.eetop.cn/blog/html/93/493893-14903.html 在使用类模板技术时,可在.h中实现,也可在.h和.cpp中分开实现,若用.h实现,不要在 ...

  9. YTU 2618: B 求类中数据成员的最大值-类模板

    2618: B 求类中数据成员的最大值-类模板 时间限制: 1 Sec  内存限制: 128 MB 提交: 430  解决: 300 题目描述 声明一个类模板,类模板中有三个相同类型的数据成员,有一函 ...

随机推荐

  1. C# 获取文件信息

    string fullPath = @"d:\test\default.avi"; string filename = Path.GetFileName(fullPath);//返 ...

  2. 【杂题】[LibreOJ #6608] 无意识的石子堆【容斥原理】【FFT】

    Description Solution 943718401=225*2^22+1 显然每行必须有两个,我们不妨枚举有k列有2个石子,那么有2(n-k)列有1个石子. \[Ans=\sum\limit ...

  3. 官网Windows 10安装程序驱动下载--截止:2019.01.06版本

    说明:鉴于win7,8不可直接再下载原装iOS文件,这份共享程序包是为以后N年做的准备.如果N年后这个包还可以用,就可以省去很多麻烦. 百度网盘分享:https://pan.baidu.com/s/1 ...

  4. Zabbix连接

    下载: wget https://fossies.org/linux/misc/zabbix-4.0.5.tar.gz 安装: https://www.cnblogs.com/sunbeidan/p/ ...

  5. kaliXSSbeef的使用

    Kali中Beef的安装和使用: 先打开终端输入 apt-get install beef-xss 然后切换到beef的安装目录 cd /usr/share/beef-xss 然后启动beef ./b ...

  6. IntelliJ IDEA 常用快捷键整理

    1. -----------自动代码--------  常用的有fori/sout/psvm+Tab即可生成循环.System.out.main方法等boilerplate样板代码 例如要输入for( ...

  7. 后盾网lavarel视频项目---5、淘宝镜像cnpm的原理及如何使用

    后盾网lavarel视频项目---5.淘宝镜像cnpm的原理及如何使用 一.总结 一句话总结: 原理:把npm上面的所有软件copy过来 使用:npm install -g cnpm --regist ...

  8. Docker非常详细的讲解

    CSDN大牛写的,推荐 http://blog.csdn.net/tangtong1/article/details/53556129 阿里云docker镜像地址: https://dev.aliyu ...

  9. Android 多分辨率与不同语言适配

    一.适配不同国家语言 智能手机系统设置里各国语言的选项,然后我们项目里可以通过资源目录实现适配语言.我们知道工程的根目录有个res/的目录,res/下有一个资源类型的目录,其中有个values/str ...

  10. Other | 十招教你找到海量PPT模板

    转载自:https://www.douban.com/note/330962457/ 问:PPT模板是什么含义? 答: 先假定你们要的是这种网上到处泛滥成灾的主题PPT吧,下面请耐心看到最后,秋叶老师 ...