8.7.2 根据类模板创建对象(1)
当使用函数模板定义的函数时,编译器能够根据函数实参的类型推断出模板类型实参。函数模板的类型形参是使用特定的函数隐式确定的。类模板有些不同。为了以类模板为基础创建对象,必须在声明中指定类名后面的类型形参。
例如,为了声明一个CSamples< >对象来处理double类型的样本,需要将声明写成下面这样:
- CSamples<double> myData(10.0);
该语句定义了一个CSamples<double>类型的对象,它可以存储double类型的样本。该对象是用值为10.0的一个样本创建的。
试一试:使用类模板
可以根据CSamples< >模板,创建一个存储CBox对象的对象。这是没有问题的,因为CBox类实现了重载大于运算符的operator>()函数。利用下面代码中给出的main()函数,我们可以练习类模板的用法:
- // Ex8_10.cpp
- // Using a class template
- #include <iostream>
- #include <utility> // For operator overload templates
- using std::cout;
- using std::endl;
- using namespace std::rel_ops;
- // Put the CBox class definition from Ex8_06.cpp here...
- // CSamples class template definition
- template <class T> class CSamples
- {
- public:
- // Constructors
- CSamples(const T values[], int count);
- CSamples(const T& value);
- CSamples(T&& value);
- CSamples() : m_Free(0) { }
- bool Add(const T& value); // Insert a value
- bool Add(T&& value); // Insert a value with move semantics
- T Max() const; // Calculate maximum
- private:
- static const size_t maxSamples = 100; // Maximum number od sample
- T m_Values[maxSamples]; // Array to store samples
- int m_Free; // Index of free location in m_Values
- };
- // Constructor template definition to accept an array of samples
- template<class T> CSamples<T>::CSamples(const T values[], int count)
- {
- m_Free = count < 100 count : 100; // Don't exceed the array
- for(int i = 0; i < m_Free; i++)
- m_Values[i] = values[i]; // Store count number of samples
- }
- // Constructor to accept a single sample
- template<class T> CSamples<T>::CSamples(T& value)
- {
- m_Values[0] = value; // Store the sample
- m_Free = 1; // Next is free
- }
- // Constructor to accept a temporary sample
- template<class T> CSamples<T>::CSamples(T&& value)
- {
- cout << "Move constructor." << endl;
- m_Values[0] = std::move(value); // Store the sample
- m_Free = 1; // Next is free
- }
- // Function to add a sample
- template<class T> bool CSamples<T>::Add(const T& value)
- {
- cout << "Add." << endl;
- bool OK = m_Free < 100; // Indicates there is a free place
- if(OK)
- m_Values[m_Free++] = value; // OK true, so store the value
- return OK;
- }
- template<class T> bool CSamples<T>::Add(T&& value)
- {
- cout << "Add move." << endl;
- bool OK = m_Free < 100; // Indicates there is a free place
- if(OK)
- m_Values[m_Free++] = std::move(value); // OK true, so store the value
- return OK;
- }
- // Function to obtain maximum sample
- template<class T> T CSamples<T>::Max() const
- {
- T theMax = m_Values[0]; // Set first sample as maximum
- for(int i = 1; i < m_Free; i++) // Check all the samples
- if(theMax < m_Values[i])
- theMax = m_Values[i]; // Store any larger sample
- return theMax;
- }
- int main()
- {
- CBox boxes[] = { // Create an array of boxes
- CBox(8.0, 5.0, 2.0), // Initialize the boxes...
- CBox(5.0, 4.0, 6.0),
- CBox(4.0, 3.0, 3.0)
- };
- // Create the CSamples object to hold CBox objects
- CSamples<CBox> myBoxes(boxes, _countof(boxes));
- CBox maxBox = myBoxes.Max(); // Get the biggest box
- cout << endl // and output its volume
- << "The biggest box has a volume of "
- << maxBox.Volume()
- << endl << endl;
- CSamples<CBox> moreBoxes(CBox(8.0, 5.0, 2.0));
- moreBoxes.Add(CBox(5.0, 4.0, 6.0));
- moreBoxes.Add(CBox(4.0, 3.0, 3.0));
- cout << "The biggest box has a volume of "
- << moreBoxes.Max().Volume()
- << endl;
- return 0;
- }