1、type-safe
type safe(类型安全)就是判断是否对正确的经过授权的内存进行访问。
"正确的"是说:比如说做类型转换,
Class1 * p1=new Class1();
Class2 * p2=(Class1 *)p1;
p2->MethodofClass1();这个时候就有可能出问题了。
可以尽量使用static_cast进行类型转换,比如说
Class2 * p2=static_cast<Class1 *>(p1);
如果转换的类型并不对应实际的基类,那么static_cast版本将会引发一个编译错误,而不是运行时错误。
"经过授权"是说:这块内存是自己的进程的可以访问的,比如说强行给一个指针赋值一个内存地址,然后强行写数据到这块内存会引发很多不安全因素,为了防止这种事情,操作系统可以检查你是否有足够的权限访问不是自己进程空间里面的内存区域(比如说操作系统的保留内存区域)。
2、C++ Template
"templates are C++ language-specific and are handled by the compiler (rather than the preprocessor) and so are type-safe."
复制一段既有程序代码的一个最平常的理由就是为了改变数据类型。
宏有它自己的缺点。第一,它只适用于简单的功能。第二个缺点比较严重:宏不提供资料型别检验,因此牺牲了C++ 的一个主要效益。第三个缺点是:宏并非函数。
C++ 提供给我们一个更好的繁殖方法:template。Templates 提供比较好的解决方案,它把「一般性的算法」和其「对资料型别的实作部份」区分开来。可以先写算法的程序代码,稍后再使用时再填入实际资料型别。新的C++ 语法使「资料型别」也以参数的姿态出现。
C++ 的template 有两种,一种针对function,另一种针对class。
A.template function
template <class T> //T作为类型的别名,在编译时能根据实际的使用场景的类型进行型别输入和判断,具有宏的代码简化功效
T power(T base, int exponent);//T在定义template的时候并没有固定类型,只有在程序代码各处实际使用此template函数的时候才确定,所以又具有重载函数的性质
B.template class
#0001 template <class T>
#0002 class CThree
#0003 {
#0004 public :
#0005 CThree(T t1, T t2, T t3);
#0006 T Min();
#0007 T Max();
#0008 private:
#0009 T a, b, c;
#0010 };
定义template类的成员函数时候,都要加上template <class T>,而且类别名称应该使用CThree<T>。
MFC 的collection classes 里头有一些是template-based,对于类型检验的功夫做得比较好。这些类别区分为:
■ 简单型- CArray、CList、CMap。它们都衍生自CObject,所以它们都具备了文件读写、执行时期型别鉴识、动态生成等性质。
■ 类型指针型- CTypedPtrArray、CTypedPtrList、CTypedPtrMap。这些类别要求你在参数中指定基础类别, 而基础类别必须是MFC 之中的non-template pointer collections,例如CObList 或CPtrArray。你的新类别将继承基础类别的所有性质。
可以把template看成是一个type checking的micro
可以认为编译器在遇到template的时候,把实际的类型代入做宏展开来保证type-safe。
比如说下面定义一个template
#include <iostream>
template <class A_Type>
int find( A_Type * array, A_Type value, int size )
{
for ( int i = 0 ; i < size ; i++ )
if ( array[i] == value ) return i ;
return -1 ;
}
下面的测试代码
int intArray[] = { 1, 3, 5, 7 } ;
float f = 5.0 ;
int index = find( intArray, f, 4 ) ;
是会编译出错的,因为它做了type checking。但macros没法定义变量类型的,当然编译器也无法
检查是否是正确的类型了。
xb
补充:micro就是一种preprocessor,而template不是