8.7.2 根据类模板创建对象(2)
应该用Ex8_06.cpp中CBox类的定义代替该程序开头相应的注释。除默认构造函数以外,该模板的所有成员函数都是通过单独的函数模板定义的,本例只是为了给出一个说明类模板用法的完整示例。CSamples类模板还包括一个构造函数和带移动语义的Add()函数来说明它们的执行过程。
在main()函数中,创建了一个包含3个CBox对象的数组,然后使用该数组初始化一个可以存储CBox对象的CSamples对象。CSamples对象的声明基本上与普通类对象的声明相同,但在模板类名称后面增加了以尖括号包围的模板类型形参。
接着用不同的方式创建moreBoxes对象。这次调用了构造函数和带移动语义的Add()函数,因为实参是rvalue。
该程序产生下面的输出:
- The biggest box has a volume of 120
- Move constructor.
- Add move.
- Add move.
- The biggest box has a volume of 120
注意,当创建类模板的实例时,不能理解成用于创建函数成员的那些函数模板的实例也被创建。编译器只创建程序中实际调用的那些成员函数的模板实例。事实上,函数模板甚至可以包含编码错误,而且只要不调用该模板生成的成员函数,编译器就不会报错。我们可以利用该示例证实这一点。试着给非移动的Add()成员的模板引入几处错误。该程序仍然能够编译和运行,因为它没有调用该Add()函数。
可以尝试修改上面的示例,看看用不同类型的模板实例化类时会发生什么事情。
注意:如果给类的构造函数添加一些输出语句,其结果会令人惊讶。CBox的构造函数被调用了103次!看一看在main()函数中究竟发生了什么。首先创建了一个包含3个CBox对象的数组,因此发生了3次调用。然后创建了一个容纳这些对象的CSamples对象,但CSamples对象包含的数组有100个CBox类型的变量,因此需要再调用默认构造函数100次,每个数组元素需要一次。当然,maxBox对象将由编译器提供的默认复制构造函数创建。