- 浏览: 533085 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (231)
- 一个操作系统的实现 (20)
- 汇编(NASM) (12)
- Linux编程 (11)
- 项目管理 (4)
- 计算机网络 (8)
- 设计模式(抽象&封装) (17)
- 数据结构和算法 (32)
- java基础 (6)
- UML细节 (2)
- C/C++ (31)
- Windows (2)
- 乱七八糟 (13)
- MyLaB (6)
- 系统程序员-成长计划 (8)
- POJ部分题目 (10)
- 数学 (6)
- 分布式 & 云计算 (2)
- python (13)
- 面试 (1)
- 链接、装载与库 (11)
- java并行编程 (3)
- 数据库 (0)
- 体系结构 (3)
- C++ template / STL (4)
- Linux环境和脚本 (6)
最新评论
-
chuanwang66:
默默水塘 写道typedef void(*Fun)(void) ...
C++虚函数表(转) -
默默水塘:
typedef void(*Fun)(void);
C++虚函数表(转) -
lishaoqingmn:
写的很好,例子简单明了,将观察者模式都表达了出来。
这里是ja ...
观察者模式——Observer
参考书 <C++ By Dissection>
In C++, there are 3 different ways to employ generic coding techniques:
void* pointers,
Templates,
Inheritance.
一、为什么使用模板进行泛型编程更好
举例:通用数组拷贝
方法一、二:使用void* 和 template
可以用void*或template来实现“通用数组拷贝 ”,但是后者 有以下优势——
(1)按元素拷贝,不依赖平台,增强可移植性 。
void*因为不知道每个元素的大小elementSize,只能将elementSize作为参数传入,但C++中类型的长度依赖平台,因此移植性不好。
(2)若源和目的数组类型不同,提供类型保护 (编译时报错unification error)。
void*不能满足这个要求。
#include <iostream> using namespace std; //ordinary int transfer1(int from[], int to[], int size){ for(int i=0;i<size;i++){ to[i]=from[i]; } return size; } //void* generic assignment function int transfer2(void* from, void* to, int elementSize, int size){ int nBytes=elementSize*size; for(int i=0;i<nBytes;i++){ static_cast<char*>(to)[i]=static_cast<char*>(from)[i]; } return size; } //template generic assignment function template<class T> int transfer3(T* from, T* to, int size){ for(int i=0;i<size;i++){ to[i]=from[i]; } return size; } template<class T> void printArr(T from[], int size){ for(int i=0;i<size;i++) cout<<from[i]<<"\t"; cout<<endl; } int main(void){ int a[10]={1,2,3,4,5,6,7,8,9,10},b[10]; double c[20]={10,9,8,7,6,5,4,3,2,1},d[20]; transfer1(a,b,10); printArr(b,10); //使用void* 只能逐字节拷贝 transfer2(c,d,8,10); printArr(d,10); //使用模板,可以仍然逐元素拷贝 d[1]++; transfer3(d,c,10); printArr(c,10); //相比void*,template仍然提供类型保护(type-safety) transfer3(a,c,10); //报错 transfer2(a,c,4,10); //不报错 system("pause"); return 0; }
方法三:使用宏定义
我来评价一下宏定义实现泛型编程的优势和劣势——
(1)宏定义优势:
简单性(Simplicity)、习惯性(familiarity)、高效性(Efficiency)。
其中,习惯性是由于在C编程中使用宏(macros)的传统;高效性主要因为没有函数调用的开销。
(2)宏定义劣势:
没有类型保护(type-safety)、预期外的计算(unanticipated evaluations)、范围问题(Scoping problem)
其中,与使用模板对比,解释一下“预期外的计算”。例如,计算立方,
可以使用宏
#define CUBE(X) ((X)*(X)*(X))
可以使用模板
template<class T> T cube(T x) {return x*x*x;}
现在需要计算(sqrt(7))³
如果使用宏,CUBE(sqrt(7)),因为是直接文本替换,计算了三次sqrt(7);
如果使用函数,cube(sqrt(7)),则只调用一次sqrt(7)。
这样一来,虽然宏没有函数调用的开销(使用对战的机制),但是重复的计算使得它的优势得不偿失:(
#include <iostream> using namespace std; #define COPY(A,B,N)\ {int i; \ for(i=0;i<(N);++i) (B)[i]=(A)[i];} template<class T> void printArr(T from[], int size){ for(int i=0;i<size;i++) cout<<from[i]<<"\t"; cout<<endl; } int main(void){ int a[10]={1,2,3,4,5,6,7,8,9,10},b[10]; double c[20]={10,9,8,7,6,5,4,3,2,1},d[20]; COPY(a,b,10); printArr(b,10); system("pause"); return 0; }
二、使用模板
1. Template Class 模板类
2. Function Templates 函数模板
Many functions have the same code body, regardless of type(例如上面的例子)
发表评论
-
C++引用计数
2013-12-29 14:48 1104主要参考《提高C++性能的编程技术》第12章 引用计数 ... -
string.h(二)C的字符串分隔函数strtok()
2013-12-19 13:25 1459char *strtok(char *str1, c ... -
关于size_t 和 ptrdiff_t 【转】
2013-12-12 18:57 820Abstract Introduction size ... -
new, operator new 和 placement new
2013-12-12 17:08 1033一、new 和 delete 的过程: 在进行一切讲解之 ... -
C/C++柔性数组 char[0]
2013-11-08 15:57 942在标准C和C++中0长数组 ... -
填充与对齐——指定变量的地址偏移【转】
2013-11-08 14:53 816转自 http://hi.baidu.com/bai_ye ... -
数组和指针并不同(总结《C专家编程chap4》)
2013-10-06 14:55 896左值(地址)和右值(地址的内容): 1. 使用数组 ... -
细说C++全局变量、局部变量和静态局部变量【转】
2013-08-15 17:17 821转自http://see.xidian.ed ... -
strcpy和strncpy用法和区别(转)
2013-07-31 17:37 31strcpy和strncpy用法和区别 转自:http ... -
stl iterator&const_iterator
2013-07-11 09:38 14iterator和const_iterator访问conta ... -
C++类对象创建过程揭密(转载)
2013-05-24 16:56 898转载:http://blog.csdn.net ... -
C调用汇编
2013-03-27 20:28 1417一、汇编语言的两种语法格式 Intel格式: 大 ... -
C++四个类型转换关键字const_cast, static_cast, dynamic_cast, reinterpret_cast
2013-02-27 10:13 2486C风格的强制类型转换( ... -
C/C++中内存模型
2012-12-30 11:07 1601一直以来,C++ ... -
map使用
2012-12-29 15:21 35需要#include <map> 定义map& ... -
C++调用C
2012-11-29 22:42 1249一般地,C++调用C有两种形式(网上资料一般没讲全): ... -
关于计算精度
2012-11-22 14:53 836本文是Sam我总结的,在C++学习过程中常见的一些涉及 ... -
C++随机数
2012-11-07 19:41 878C++随机数 #include<iostream ... -
C文件操作(一)
2012-11-07 19:11 1574C文件操作(流式文件 &a ... -
C++中的内联函数inline
2012-07-13 19:16 1037在c++中,为了解决一些频繁调用的小函数大量消耗栈空间或者 ...
相关推荐
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息队列系统。 Java文件上传组件 COS FAT文件系统读写类库 fat32-lib ...
在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天...
在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天...