STL中Straits技术

来源:互联网 发布:知其然的然是什么意思 编辑:程序博客网 时间:2024/05/16 02:29

traits技术:
        STL标准模板库非常强调软件的复用,而traits技术是采用的重要手段。traits的中文意思就是特性,traits就像萃取机,提取不同类的共性,以便能统一处理。traits依靠显示模板特化来把代码中因类型不同而发生变化的片段拖出来,用统一的接口来包装。这个接口可以包含一个c++类所能包含的任何东西,如内嵌类型、成员函数、成员变量。作为客户的模板代码,可以通过traits模板类所提供的公共接口来间接访问。下面通过一个简单的例子加以说明:

#include "stdafx.h"
#include <iostream>
using std::cout;
using std::endl;

class CIntArray
{
 int a[10];
public:
 CIntArray()
 {
  for (int i = 0 ; i < 10 ; i++)
  {
   a[i] = i + 1; //把1到10这10个数存储到数组a中
  }
 }

 int GetSum(int times)
 {
  int sum = 0;
  for (int i = 0 ; i < 10 ; i++)
  {
   sum += a[i];
  }
  return sum * times;
 }
 
};

class CFloatArray
{
 float f[10];
public:
 CFloatArray()
 {
  for (int i = 1 ; i <= 10 ; i++)
  {
   f[i-1] = 1.0f / i; //把1到10这10个数存储到数组a中
  }
 }

 float GetSum(float times)
 {
  float sum = 0.0f;
  for (int i = 0 ; i < 10 ; i++)
  {
   sum += f[i];
  }
  return sum * times;
 }
 
};

//int main(int argc, char* argv[])
//{
// CIntArray intArray;
// CFloatArray floatArray;
// cout << "整形数组和3的倍数" << intArray.GetSum(3) << endl;
// cout << "浮点数组和3.2的倍数" << intArray.GetSum(3.2f) << endl;
// return 0;
//}


//解说:
// 程序功能简单,即把整形数组或浮点数组的和乘以相应的倍数并输出。CIntArray与CFloatArray的功能相似,main函数通过调用相应类的GetSum函数来
// 完成。那么能否通过一个类的接口函数来完成上述功能呢?可以,当然要用到模板,增加一个类CApply,代码如下:

template <class Type>
class CApply
{
public:
 float GetSum(Type & t, float inpara)
 {
  return t.GetSum(inpara);
 }
};


//main函数中的代码变为如下:

int main(int argc, char* argv[])
{
 CIntArray intArray;
 CFloatArray floatArray;
 CApply<CIntArray> c1;
 CApply<CFloatArray> c2;
 cout << "整形数组和3的倍数" << c1.GetSum(intArray, 3) << endl;
 cout << "浮点数组和3.2的倍数" << c2.GetSum(floatArray, 3.2f) << endl;
 return 0;
}


通过类模板CApply接口函数实现了对整数数组和浮点数组类的操作,如果这部分完全明白的话,那么说明你的思维有一定的提高。但是仔细分析一下,细节处还是有问题的:比如CIntArray类中的GetSum函数返回的是整型,形参为整型;CFloatArray类中的GetSum函数返回值是浮点型,形参为浮点型,虽然从结果上看正确,但是从严格角度来说不够严密。如果问题复杂了,问题就会出来的。那么如何解决输入、输出参数类型的不同呢?traits技术及时很哈的解决。
有三个步骤:
第一步:定义基本模板类

class  <class Type>
class NumTraits
{
};

NumTraits可以什么都不写,只是说明类是一个模板类。

第二步:模板特化。本例是针对CIntArray和CFloatArray的,因此代码如下:

template<>
class NumTarits<CIntArray>
{
public:
 typedef int ResultType;
 typedef int InputPara;
};

template<>
class NumTarits<CFloatArray>
{
public:
 typedef int ResultType;
 typedef int InputPara;
};


第三步:统一模板调用类编制

template <class Type>
class CApply
{
public:
 NumTarits<Type>::ResultType GetSum(Type & obj, NumTraits<Type>::InputPara in)
 {
  return obj.GetSum(in);
 }
};

原创粉丝点击