⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 12章 模板.txt

📁 C++大学教程txt版中文版 C++大学教程txt版中文版
💻 TXT
📖 第 1 页 / 共 3 页
字号:
    性能提示12.2
    如果可能,在编译时指定容器类(如数组类和堆栈类)的长度(可能通过非类型模板长度参数)可以消除用new动态生成空间的执行时开销。

    软件工程视点12.3
    如果可能,在编译时指定容器类的长度(可能通过非典型模板长度参数)以避免new无法取得所要内存时造成致命的造行时错误。

    练习中要用无类型参数生成第8章开发的Array类的模板。这个模板可以用编译时指定类型的指定元素个数实例化Array对象,而不必在运行时动态生成Array对象的空间。
    不符合常用类模板的特定类型的类可以重定义该类型的类模板。例如,可以用一个Array类模板实例化任何类型的数组。程序员可以控制某个类型Array类的实例化,如Martian,只要建立类名为Array<Martian>的新类即可。

12.6模板与继承
    模板与继承关系如下所示:
    ●类模板可以从模板类派生。
    ●类模板可以从非模板类派生。
    ●模板类可以从类模板派生。
    ●非模板类可以从类模板中派生。

12.7  模板与友元
 函数和整个类都可以声明为非模板类友元。使用类模板,可以声明各种各样的友元关系。友元可以在类模板与全局函数间、另一个类(可能是模板类)的成员函数间或整个类中(可能是模板类)建立。建立这种友元关系的符号可能很繁琐。
    在下列X类的类模板中声明为:
    template<class T>class X
下列友元声明:
    friend void f1();
使函数f1成为从上述类模板实例化的每个模板类的友元。
    在下列X类的类模板中声明为:
    template<class T>class X
下列友元声明:
    friend void f2(X< T >  6);
对特定类型T(如float)使函数f2(X<float>&)成为X<float>的友元。
    在类模板中,可以声明另一个类的成员函数是类模板产生的任何模板类的友元。只要用类名和二元作用域运算符指定其它类的成员函数名。例如,在下列X类的类模板中声明为:
    template<class T>class X
下列友元声明:
    friend void A::f4();
使A类的成员函数f4成为上述类模板实例化的任何模板类的友元。
    在下列X类的类模板中声明为:
    template<class T>class X
下列友元声明:
    friend void  C< T >::f5( X< T > & );
  对特定类型T(如float)使成员函数:
    C<float>::f5( X< float> & );
成为X<float>模板类的友元函数。
    在下列X类的类模板中声明为:
    template<Class T>Class X
  可以声明第二个类Y,如下所示:
    friend class Y;
  使Y类的每个成员函数成为X的类模板产生的每个模板类的友元。
    在下列X类的类模板中声明为:
    template<class T>class X
  可以声明第二个类Z,如下所示:
    friend class  Z< T >;
  使模板类用特定类型T(如float)实例化时,class Z<float>的所有成员成为模板类X<float>的友元。

12.8  模板与static成员
    在非模板类中,类的所有对象共享一个static数据成员,Static数据成员应在文件范围内初始化。
    从类模板实例化的每个模板类有自己的类模板static数据成员,该模板类的所有对象共享一个Static数据成员。和非模板类的static数据成员一样,模板类的static数据成员也应在文件范围内初始化。每个模板类有自己的类摸板的static数据成员副本。


小  结
    ●模板使我们可以用一个代码段指定一组相关函数(称为模板函数)或一组相关类(称为模板类)。
    ●程序员对函数模板的定义只编写一次。基于调用函数时提供的参数类型,C++自动产生单独的函数来正确地处理每种类型的调用。这些都是利用程序源代码的剩余空间进行编译。
    ●所有函数模板定义都足用关键字template开始的,该关键字之后是用尖括号<>括起来的形式参数表。函数模板的每个形式类型参数之前应有关键字class(或新的关键字typename)。关键字class指定函数模板的类型参数,实际上表示“任何内部类型或用户自定义类型”。
    ●模板定义的形式参数可用来指定传递给函数的参数类型、函数返回类型和声明函数中变量。
    ●形式参数的名字可以只在模板的形式参数表中出现一次。同一个形式参数名可用于多个模板函数。
    ●函数模板本身可以用多种方式重载。我们可以提供其他函数模板,指定不同参数的相同函数名。函数模板也可以用其他非模板函数(同名而不同参数)重载。
    ●类模板提供了描述一个类和实例化类(即该通用类指定类型的版本)的方法。
    ●为了说明如何定制通用类模板以形成指定的模板类,类模板需要类型参数,所以类模板也常常称为参数化类型。
    ●要使用模板类的程序员只需简单地编写一个类模板。在需要用模板建立一个新的指定类型的类时,程序员只需要用一种简洁的表示方法,编译器就会写出该模板类的源代码。
    ●类模板的定义似乎与普通的类定义没什么不同,除了使用template<class T>指明这是一个带类型参数T(指明创建的类的类型)的类模板定义。在类首部和成员函数的定义中,类型
    ●作为一个通用的类型名。
    ●在类模板首部以外的成员函数定义都要以template<class T>开头。接着,成员函数的定义与普通成员函数的定义相似,只是类中的数据通常用类型参数T表示。二元作用域运算符总是把成员函数的定义与正确的类范围联系起来。
    ●类模板首部也可以使用无类型参数。
    ●特定类型的类可以重定义该类型的类模板。
    ●类模板可以从模板类派生。类模板可以从非模板类派生。模板类可以从类模板派生。非模板类可以从类模板中派生。
    ●函数和整个类都可以声明为非模板类的友元。使用类模板,可以声明各种各样的友元关系。
    友元可以在类模板与全局函数间、另一个类(可能是模板类)的成员函数间或整个类中(可能是模板类)建立。
    ●从类模板实例化的每个模板类有自己的类模板的Static数据成员.该模板类的所有对象共享一个static数据成员。和非模板类的static数据成员一样,模板类的Static数据成员也应在文件范围内初始化。
    ●每个模板类有该类模板的static数据成员副本。


术  语
angle brackets   尖括号                            keyword temPlate   关键字template
class template   类模板                         non-type parameter in a templateheader模板首
class template name  类模板名                        部中的无类型参数
formal parameter in a template header   模  overloading a template function  重载模板函数
  板首部中的形式参数                               parameterized type   参数化类型
friend of a template   模板的友元                  static data member of a class template  
function template  函数模板                               类模板的static 数据成员
function temPlate declaration  函数模板的声明      static data member of a template class  模
function template definition  函数模扳的定义              板类的static数据成员
keyworde class in a template type parameter  模板  static member function of a class template  
  类型参数中的关键字class                                 类模板的static成员函数
static member function of a template class  模板类 template argument  模板实参
    的static成员函数                               template name  模板名
template class  模板类                             template parameter  模板形参
template class member function  模板类成员函数     type parameter in a template header  模板
template<class T>    类型参数                             首部的
template function  模板函数                        typename


自测练习

12.1 判断下列各题是否正确。如果不正确,请说明原因。
    a)函数模板的友元函数必须是模板函数。
    b)如果从一个带单个static数据成员的类模板产生几个模板类,则每个模板类共享类模板static数据成员的一个副本。
    c)模板函数可以用同名的另一模板函数重载。
    d)形式参数的名字可以只在模板函数的形式参数表中出现一次。同一个形式参数名只能用于一个模板函数。
    e)关键字class指定函数模板类型参数,实际上表示“任何用户自定义类型”。

12.2填空:
    a)模板使我们可以用一个代码段指定一组相关函数(称为——)或一组相关类(称
    ——)。
    b)所有的函数模板定义都是以关键字——开始的,该关键字之后是用——括起
    来的形式参数表。
    c)从一个函数模板产生的相关函数都同名,因此编译器用——的解决方法调用相应
    函数。
    d)类模板也称为——类型。
    e)——运算符和模板类名一起将每个成员函数定义与类模板的范围相关联。
    f)和非模板类的static数据成员一样,模板类的static数据成员也应在——范围
    内初始化。


自测练习答案
 12.1  
    a)不正确。也可以用非模板函数。
    b)不正确。每个模板类有自己的静态数据成员副本。
    c)正确。
    d)不正确。模板函数间的形式参数名不必惟一。
    e)不正确。这里的关键字class也允许内部类型的参数类型。
  12.2
    a)模板函数、模板类。
    b)template、尖括号(<>)。
    c)重载。
    d)参数化。
    e)二元作用域。
    f)文件。


练  习
    12.3  根据图5.15的排序程序编写函数摸板bubbleSort。编写一个驱动程序,输入、排序和输出int数组与float数组。
    12. 4  重载图12.2的函数模板printArray,使其取另外两个整数参数int lowSubscript和int highSubscript。调用这个函数只打印数组中的指定部分。验证lowSubscript和highSubscript。如果其中一个值超界或highSubscript小于等于lowSubscript,则重载的printArray函数返回0,否则printArray返回打印的元素个数。然后修改main,对数组a、b、c使用两个版本的printArray。一定要测试两个版本的printArray的各种可能情况。
    12.5  用非模板版本重载图12.2的函数模板prinlArray,使其以整齐的表格式分栏格式打印字符串数组。
    12.6  编写判定函数isEqualTo的简单函数模扳,用相等运算符比较其两个参数,如果相等则返回1,如果不相等则返回0。使用这个函数模扳,使得程序中对各种内部类型调用isEqualTo。现在编写程序的另一种形式,对用户自定义类的类型调用isEqualTo,但不重载相等运算符。运行这个程序时会发生什么情况?重载相等运算符(用运算符函数
    operator==),运行这个程序时会发生什么情况?
    12.7  用无类型参数numberOfElements和类型参数elementType生成第8章开发的Array类模板。这个模板按编译时指定个数的指定元素类型实例化Array对象。
    12.8  编写一个使用类模板Array的程序,模板可以实例化任何元素类型的Array对象。用float元素的Array(class Array<float>)重定义模板。驱动程序演示通过模板实例化int类型的Array,并使用class Array<float>中提供的定义实例化float类型的Array。
    12. 9  试区分模板函数与函数模板。
    12. 10类模板与模板类哪个像是能够绘制形状的模扳?为什么?
    12.11函数模板与重载有什么关系?
    11. 12为什么选择函数模板而不选择宏?
    12.13使用函数模板与类模板可能造成哪些性能问题?
    12.14编译器通过匹配过程确定函数调用时调用哪个模板函数。什么情况下进行匹配会造成编译错误?
    12.15为什么类模板也称为参数化类型?
    12.16解释C++程序中使用下列语句的原因。
       Array<Employee>workerList(100);
    12.17分析练习12.16的答案,解释C++程序中使用下列语句的原因。
        Array<Employee>workerList;
    12.18解释C++程序中使用下列语句的原因。
       template< class T >  Array< T >::Array( int s )
    12.19为什么数组、堆栈之类的容器类模板通常用无类型参数?
    12.20说明如何提供特定类型的类重定义该类型的类模板。
    12.21说明类模板与继承的关系。
    12.22假设类模板的首部如下:
    template<class T1>class C1
    说明类模板首部中用下列友元声明时的友元关系。以f开头的标识符是函数,以C开头的标识符是类,以T开头的标识符是任何类型(即内部类型或类类型)。
    a)friend void f1();
    b)friend void f2(C1< T1 > &);
    c)friend void C2::f4();
    d)friend void C3<T1>::f5(C1<T1>&);
    e)friend class C5;
    f)friend class C6<T1>;
    12.23假设类模板Employee有static数据成员count。假设从类模板实例化三个模板类。那么有多少个static数据成员?各有什么限制(如果有)?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -