设为首页 加入收藏

TOP

8.5.2 根据类模板创建对象
2013-10-07 12:30:28 来源: 作者: 【 】 浏览:66
Tags:8.5.2 根据 模板 创建 对象

8.5.2  根据类模板创建对象

当我们使用函数模板定义的函数时,编译器能够根据使用的实参类型生成函数。函数模板的类型形参是通过使用特定的函数隐式确定的。类模板有些不同。为了以类模板为基础创建对象,我们必须在声明中指定类名后面的类型形参。

例如,为了声明一个CSamples<>对象来处理double类型的样本,需要将声明写成下面这样:

  1. CSamples<double> myData(10.0); 

该语句定义了一个CSamples<double>类型的对象,它可以存储double类型的样本。该对象是用值为10.0的一个样本创建的。

试一试:类模板

我们可以根据CSamples<>模板,创建一个存储CBox对象的对象。这是没有问题的,因为CBox类实现了重载大于运算符的operator>()函数。利用下面代码中给出的main()函数,我们可以练习类模板的用法:

  1. // Ex8_07.cpp  
  2. // Using a class template  
  3. #include <iostream> 
  4. using std::cout;  
  5. using std::endl;  
  6.  
  7. // Put the CBox class definition from Ex8_06.cpp here...  
  8.  
  9. // CSamples class template definition  
  10. template <class T> class CSamples  
  11. {  
  12. public:  
  13. // Constructors  
  14. CSamples(const T values[], int count);  
  15. CSamples(const T& value);  
  16. CSamples(){ m_Free = 0; }  
  17.  
  18. bool Add(const T& value);   // Insert a value  
  19. T Max() const;  // Calculate maximum  
  20.  
  21. private:  
  22. T m_Values[100];                // Array to store samples  
  23. int m_Free;                 // Index of free location in m_Values  
  24. };  
  25.  
  26. // Constructor template definition to accept an array of samples  
  27. template<class T> CSamples<T>::CSamples(const T values[], int count)  
  28. {  
  29. m_Free = count < 100  count:100;            // Don't exceed the array  
  30. for(int i = 0; i < m_Free; i++)  
  31. m_Values[i] = values[i];        // Store count number of samples  
  32. }  
  33.  
  34. // Constructor to accept a single sample  
  35. template<class T> CSamples<T>::CSamples(const T& value)  
  36. {  
  37. m_Values[0] = value;                // Store the sample  
  38. m_Free = 1;         // Next is free  
  39. }  
  40.  
  41. // Function to add a sample  
  42. template<class T> bool CSamples<T>::Add(const T& value)  
  43. {  
  44. bool OK = m_Free < 100;     // Indicates there is a free place  
  45. if(OK)  
  46. m_Values[m_Free++] = value;                 
    // OK true, so store the value  
  47. return OK;  
  48. }  
  49.  
  50. // Function to obtain maximum sample  
  51. template<class T> T CSamples<T>::Max() const  
  52. {  
  53. theMax = m_Free   m_Values[0] : 0;       
    // Set first sample or 0 as maximum  
  54. for(int i = 1; i < m_Free; i++)         // Check all the samples  
  55. if(m_Values[i] > theMax)  
  56. theMax = m_Values[i]; // Store any larger sample  
  57. return theMax;  
  58. }  
  59.  
  60. int main()  
  61. {  
  62. CBox boxes[] = { // Create an array of boxes  
  63. CBox(8.0, 5.0, 2.0),        // Initialize the boxes...  
  64. CBox(5.0, 4.0, 6.0),  
  65. CBox(4.0, 3.0, 3.0)  
  66. };  
  67.  
  68. // Create the CSamples object to hold CBox objects  
  69. CSamples<CBox> myBoxes(boxes, sizeof boxes / sizeof CBox);  
  70.  
  71. CBox maxBox = myBoxes.Max(); // Get the biggest box  
  72. cout << endl // and output its volume  
  73. << "The biggest box has a volume of "  
  74. << maxBox.Volume()  
  75. << endl;  
  76. return 0;  

我们应该用本章前面Ex8_06.cpp文件中CBox类的定义代替该程序开头相应的那行注释。不必担心支持CBox对象与double类型数值进行比较的operator>()函数,因为本示例不需要该函数。除默认构造函数以外,该模板的所有成员函数都是通过单独的函数模板定义的,本例只是为了给出一个说明类模板用法的完整示例。

在main()函数中,我们创建了一个包含三个CBox对象的数组,然后使用该数组初始化一个可以存储CBox对象的CSamples对象。CSamples对象的声明基本上与普通类对象的声明相同,但在模板类名称后面增加了以尖括号包围的类型形参。

该程序产生下面的输出:

  1. The biggest box has a volume of 120 

注意,当我们创建类模板的实例时,不能理解成用于创建函数成员的那些函数模板的实例也被创建。编译器只创建程序中实际调用的那些成员函数的模板实例。事实上,我们的函数模板甚至可以包含编码错误,而且只要不调用该模板生成的成员函数,编译器就不会报错。我们可以利用该示例证实这一点。试着给Add()成员的模板引入几处错误。该程序仍然能够编译和运行,因为它没有调用Add()函数。

我们可以尝试修改上面的示例,看看用不同类型的模板实例化类时,可能会发生什么事情。

注意:

如果给类的构造函数添加一些输出语句,其结果会让我们对此感到惊讶。CBox的构造函数被调用了103次!看一看在main()函数中究竟发生了什么。我们首先创建了一个包含三个CBox对象的数组,因此发生了三次调用。然后创建了一个容纳这些对象的CSamples对象,但CSamples对象包含的数组有100个CBox类型的变量,因此需要再调用默认构造函数100次,每个数组元素需要一次。当然,maxBox对象将由编译器提供的默认复制构造函数创建。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇8.1.2 默认的析构函数 下一篇8.4.4 重载加法运算符

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: