使用模板的目的就是能够让程序员编写与类型无关的代码。假定我们希望编写一个函数来比较两个值,并指出第一个值是小于、等于还是大于第二个值。在实际中,我们可能想要定义多个函数,每个函数比较一种给定类型的值。
注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。
1
、函数模板的格式:
template
<
class
形参名
,
class
形参名,
......
>
返回类型
函数名
(
参数列表
)
模板定义以关键字template开始,后跟一个模板参数列表,这是一个逗号分隔的一个或多个模板的列表,用< >包围起来。
class
可以用
typename
关见字代替
,在这里
typename
和
class
没区别
,<>
括号中的参数叫
模板形参
,模板形参和函数形参很相像,
模板形参不能为空。
注意:对于函数模板而言不存在
h(int,int)
这样的调用,
不能在函数调用的参数中指定模板形参的类型,对函数模板的调用应使用
实参推演
来进行
,即只能进行
h(2,3)
这样的调用,或者
int a, b; h(a,b)
。
2
、类模板的格式为:
template
<
class
形参名
,
class
形参名
,
…
>
class
类名
{... };
类模板和函数模板都是以
template
开始后接模板形参列表组成,模板形参不能为空,
一但声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数,即可以在类中使用内置类型的地方都可以使用模板形参名来声明。
如何根据模板中数据类型做对应操作?
读取.txt文件中保存的Inertial measurement units (IMU)数据,并根据模版中数据类型做对应操作。这里存储了Gyroscope、Accelerometer和Magnetometer传感器的数据,还保存了采样时间的数据。怎么使用模板来读取这些存储在txt文件中的数据?
//sensor数据格式,每个sensor对应三个值
struct FORMAT
double x;
double y;
double z;
//AHRS记录的数据
struct GYRODATA
vector<FORMAT> gyroscopeData;//陀螺仪
vector<FORMAT> accelerometerData;//加速度计
vector<FORMAT> magnetometerData;//电子罗盘
vector<double> timeData;
//根据模版中数据类型做对应操作
template <typename T>
struct Type2Type
typedef T type;
template <typename T>
inline void sscanfData(const char* buf,T& tempData,Type2Type<double>)
sscanf(buf,"%lf",&tempData);
template <typename T>
inline void sscanfData(const char* buf,T& tempData,Type2Type<FORMAT>)
sscanf(buf,"%lf %lf %lf",&tempData.x,&tempData.y,&tempData.z);
//获取数据
template <class T>
void getDatafromTxt(const string filename,vector<T>& vecData)
char buf[1024]; //临时保存读取出来的文件内容
string message;
ifstream infile;
infile.open(filename);
if(infile.is_open()) //文件打开成功,说明曾经写入过东西
while(infile.good() && !infile.eof())
memset(buf,0,1024);
infile.getline(buf,1024);
T tempData;
sscanfData(buf,tempData,Type2Type<T>());//根据模版中数据类型做对应操作
//sscanf(buf,"%lf %lf %lf",&tempData.x,&tempData.y,&tempData.z);
vecData.push_back(tempData);
infile.close();
else cout<<"file open failed..."<<endl;
int main()
//读取存储的sensor数据
GYRODATA GyroData;
getDatafromTxt("Gyroscope.txt",GyroData.gyroscopeData);
getDatafromTxt("Accelerometer.txt",GyroData.accelerometerData);
getDatafromTxt("Magnetometer.txt",GyroData.magnetometerData);
getDatafromTxt("time.txt",GyroData.timeData);
return 0;
Effective C++(编程的50个细节)
Effective C++(编程的50个细节)着重讲解了编写C++程序应该注意的50个细节问题,书中的每一条准则描述了一个编写出更好的C++的方式,每一个条款的背后都有具体范例支持,书中讲的都是C++的编程技巧和注意事项,很多都是自己平时不太注意但又很重要的内容,绝对经典,作者Scott Meyers是全世界最知名的C++软件开发专家之一。
电子书PDF格式下载:http://www.yanyulin.info/pages/2013/11/effective.html
1、从C转向C++
条款1:尽量用CONST和INLINE而不用#DEFINE
条款2:尽量用而不用
条款3:尽量用NEW和DELETE而不用MALLOC和FREE
条款4:尽量使用C++风格的注释
2、内存管理
条款5:对应的NEW和DELETE要采用相同的形式
条款6:析构函数里对指针成员调用DELETE
条款7:预先准备好内存不够的情况
条款8:写OPERATOR NEW与OPERATOR DELETE要遵循常规
条款9:避免隐藏标准形式的NEW
条款10:如果写了OPERATOR NEW就要同时写OPERATOR DELETE
条款11:为需要动态分配内存的类声明一个拷贝构造函数和一个赋值函数
条款12:尽量使用初始化而不要在构造函数里赋值
条款13:初始化列表中成员列出顺序和它们在类中的声明顺序相同
条款14:确定基类有虚析构函数
条款15:让OPERATOR=返回*THIS的引用
条款16:在OPERATOR=中对所有数据成员赋值
条款17:在OPERATOR=中检查给自已赋值的情况
3、类和函数:设计与声明
条款18:争取使类的接口完整并且最小
条款19:分清成员函数,非成员函数和友元函数
条款20:避免PUBLIC接口出现数据成员
条款21:尽可能使用CONST
条款22:尽量用传引用而不用传值
条款23:必须返回一个对象时不要试图返回一个引用
条款24:在函数重载与设定参数默认值间慎重选择
条款25:避免对指针与数字类型的重载
条款26:当心潜在的二义性
条款27:如果不想使用隐式生成的函数要显示的禁止它
条款28:划分全局名字空间
4、类和函数:实现
条款29:避免返回内部数据的句柄
条款30:避免这样的成员函数,其返回值是指向成员的非CONST指针或引用
条款31:千万不要返回局部对象的引用,也不要返回函数内部用NEW初始化的指针
条款32:尽可能推迟变量的定义
条款33:明智的使用INLINE
条款34:将文件间的编译依赖性阡至最低
5、继承与面向对象设计
条款35:使公有继承体现是一个的函义
条款36:区分接口继承与实现继承
条款37:绝不要重新定义继承而来的非虚函数
条款38:绝不要重新定义继承而来的缺省参数值
条款39:避免向下转换继承层次
条款40:通过分层来体现有一个和用...来实现
条款41:区分继承和模板
条款42:明智的使用私有继承
条款43:明智的使用多继承
条款44:说你想说的,理解你说的
条款45:弄清C++在幕后为你所写、所调用的函数
条款46:宁可编译与链接时出错,也不要运行时出错
条款47:确保非局部静态对象在使用前被初始化
条款48:重视编译器警告
条款49:熟悉标准库
条款50:提高对C++的认识
转载自:http://blog.csdn.net/mykoma521/archive/2010/06/14/5670988.aspx在C++中,使用template,有时候可能会需要得到当前所使用的类型.本文中使用两种办法来。TT类为使用模板的类,TT.h#ifndef _TT_H#define _TT_H#include "stdio.h"template <class T>clas...
条款8: 写operator new和operator delete时要遵循常规
条款9: 避免隐藏标准形式的new
条款10: 如果写了operator new就要同时写operator delete
第三章 构造函数,析构函数和赋值操作符
条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符
条款12: 尽量使用初始化而不要在构造函数里赋值
条款13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同
条款14: 确定基类有虚析构函数
条款15: 让operator=返回*this的引用
条款16: 在operator=中对所有数据成员赋值
条款17: 在operator=中检查给自己赋值的情况
第四章 类和函数:设计与声明条款
条款18: 争取使类的接口完整并且最小
条款19: 分清成员函数,非成员函数和友元函数
条款20: 避免public接口出现数据成员
条款21: 尽可能使用const
条款22: 尽量用“传引用”而不用“传值”
条款23: 必须返回一个对象时不要试图返回一个引用
条款24: 在函数重载和设定参数缺省值间慎重选择
条款25: 避免对指针和数字类型重载
条款26: 当心潜在的二义性
条款27: 如果不想使用隐式生成的函数就要显式地禁止它
条款28: 划分全局名字空间
第五章 类和函数: 实现
条款29: 避免返回内部数据的句柄
条款30: 避免这样的成员函数:其返回值是指向成员的非const指针或引用,但成员的访问级比这个函数要低
条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引
条款32: 尽可能地推迟变量的定义
条款33: 明智地使用内联
条款34: 将文件间的编译依赖性降至最低
第六章 继承和面向对象设计
条款35: 使公有继承体现 "是一个" 的含义
条款36: 区分接口继承和实现继承
条款37: 决不要重新定义继承而来的非虚函数
条款38: 决不要重新定义继承而来的缺省参数值
条款39: 避免 "向下转换" 继承层次
条款40: 通过分层来体现 "有一个" 或 "用...来实现"
条款41: 区分继承和模板
条款42: 明智地使用私有继承
条款43: 明智地使用多继承
条款44: 说你想说的;理解你所说的
第七章 杂项
条款45: 弄清C++在幕后为你所写、所调用的函数
条款46: 宁可编译和链接时出错,也不要运行时出错
条款47: 确保非局部静态对象在使用前被初始化
条款48: 重视编译器警告
条款49: 熟悉标准库
条款50: 提高对C++的认识
wings是一款用于单元测试测试用例驱动框架自动生成工具,这款工具主要是全自动生成单元测试驱动代码与测试数据。解决做单元测试耗时耗力,编写难度大等问题。提升开发和测试效率。 特点: (1) 程序参数深度分析问题 Wings通过编译器底层技术,将输入的源文件,按照函数为单位,形成模块对象。对象中包含函数的输入参数,返回值类型等信息,供驱动函数模块和测试用例模块使用。每个文件作为一个单元,针对其中的每个函数的每个参数进行深度解析,对于嵌套类型,复杂类型等都可以实现精确的解析和分解,将复杂类型逐层讲解为基础数据类型,并产生参数结构的描述文件(PSD)。 (2) 函数驱动自动生成模块 依据PSD文件的格式信息,自动生成被测源程序的所有驱动函数,单元测试过程不再依赖开发人员手动编写测试函数,只需将生成的驱动函数和被测源文件一起编译,即可执行测试并查看测试结果。测试驱动自动生成程序基于PSD描述,全自动构建驱动被测程序运行的所有参数,必须的全局变量,并可根据复杂变量的层级结构产生结构化的测试驱动程序,可以节省大量的单元测试用例的编写时间。 (3) 测试数据自动生成与管理 用于自动生成测试数据,测试数据与被测函数提取的信息相互对应,数据以一定的层次逻辑关系存 储在json文件中。数据和经过分解和展开后的数据类型是一一对应的。这些数据用户可以根据业务要求随意边际,并且用json文件进行结构化,层次化展示,非常的清晰。其中的测试数据包括全局变量值、被测函数调用时的参数值。 优点: 1. 可以为任意复杂参数结构C语言开发的系统全自动生成测试驱动程序 2. 可完成对于被测试函数的参数进行多层编译解析,并完成复杂参数赋值的代码的自动生成。 3. 支持被测函数引用的全局变量的分析和自动赋值程序的生成。 4. 能够区分系统变量和用户变量,对于复杂的系统变量可由用户自定义赋值模板。 例如File类型,而不是把复杂的系统变量全部展开。 5. 支持多层次的可视化的数据表格来对变量进行赋值,而无需关注驱动程序本身。 数据表格可以表达任意深度和多层次的数据关系,用户只需要对表格数据进行编辑,自动生成的驱动程序会自动完成表格数据的读取和参数赋值的构造过程。 6. Wings支持所有C语言的数据类型(基础类型,结构体,指针,数组,枚举等)以及高层级数据结构。 例如链表的分析和对应的驱动和数据表格框架的生成。 7. Wings生成的代码与人工写的非常相近,可读性强,自带注释和按照层次的缩进和代·码编排。
模板是泛型编程的基础,泛型编程即以一种 独立于任何特定类型 的方式编写代码。
模板是创建泛型或函数的蓝图或公式。容器、迭代器、算法等,都是泛型编程的例子。
在C++中,模板分为函数模板和类模板两种。
1. 函数模板:
函数模板不是一个实在的函数,编译器不能为其生成可执行代码。
定义函数模板后只是一个对参数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
编译器由模板自动生成函数时,会用具体的类型名对模板中所有的类型参数进行替换,其他部分则原封不动的保留。
同一个类型参数只能替换
【C++】C++模板一. 模板概论二. 函数模板三. 函数模板和普通函数的区别四. 函数模板和普通函数一起用的调用规则五. 模板机制剖析六. 模板的局限性七. 类模板八. 类模板的应用
一. 模板概论
c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来代表。这个通用函数就成为函数模板。凡是函数体相同...
类模板使用户可以为类声明一种模式,使得类中的某些数据成员、成员函数的参数和返回值能取任意数据类型。类模板用于实现类所需数据的类型参数化。类模板在表示数据结构(如数组、二叉树和图等)时显得特别重要,这些数据结构的表示和算法不受所包含的元素类型的影响。
类模板的声明格式如下:
模板是c++的一种特性,允许函数或者类(对象)通过泛型(generic types)的形式表现或者运行,模板可以使得函数或类在对应不同的类型(types)的时候正常工作,而无需为每一种类型分别写一份代码。
普通函数的重载普通函数重载很简单,只要参数不一样即可,如下:void fun(){};
void fun(int a, int b){};模板函数的重载模板函数重载如下:template<class T>
void test(T p1){
cout<<"test(T p1)"<<endl;
}template<class T>
void test(T p1, T p2){
1、std::shared_ptr
shared_ptr是一种智能指针(smart pointer),作用有如同指针,但会记录有多少个shared_ptrs共同指向一个对象。这便是所谓的引用计数(reference counting)。
一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。
std::condition_variable 是条件变量,更多有关条件变量的定义参考维基百科。Linux 下使用 Pthread 库中的 pthread_cond_*() 函数提供了