如何在类模板外定义成员函数
- 格式:docx
- 大小:61.03 KB
- 文档页数:3
c++类模板template中的typename使⽤⽅法-超级棒转载:https:///vanturman/article/details/80269081近⽇,看到这样⼀⾏代码:typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;看起来它应该是定义⼀个类型别名,但是typedef不应该是像这样使⽤么,typedef+原类型名+新类型名:typedef char* PCHAR;可为何此处多了⼀个typename?另外__type_traits⼜是什么?看起来有些眼熟,想起之前在Effective C++上曾经看过traits这⼀技术的介绍,和这⾥的__type_traits有点像。
只是⼀直未曾遇到需要traits的时候,所以当时并未仔细研究。
然⽽STL中⼤量的充斥着的traits,⼀查才发现原来它是⼀种⾮常⾼级的技术,在更现的⾼级语⾔中已经很普遍。
因此这次花了些时间去学习它,接下来还有会有另⼀篇⽂章来详细介绍C++的traits技术。
在这⾥,我们暂时忘记它,仅将它当成⼀个普通的类,先来探讨⼀下这个多出来的typename是怎么回事?typename的常见⽤法对于typename这个关键字,如果你熟悉C++的模板,⼀定会知道它有这样⼀种最常见的⽤法(代码摘⾃C++ Primer)// implement strcmp-like generic compare function// returns 0 if the values are equal, 1 if v1 is larger, -1 if v1 is smallertemplate <typename T>int compare(const T &v1, const T &v2){if (v1 < v2) return -1;if (v2 < v1) return1;return0;}也许你会想到上⾯这段代码中的typename换成class也⼀样可以,不错!那么这⾥便有了疑问,这两种⽅式有区别么?查看C++ Primer之后,发现两者完全⼀样。
C++类的定义和对象C++类的定义和对象类的成员变量称为类的属性(Property),将类的成员函数称为类的⽅法(Method)。
在⾯向对象的编程语⾔中,经常把函数(Function)称为⽅法(Method)。
类的定义class Student{public://成员变量char *name;int age;float score;void say(){cout<<name<<age<<score<<endl;}};类只是⼀个模板(Template),编译后不占⽤内存空间.class C++ 中新增的关键字,⽤来定义类。
成员变量和成员函数,它们统称为类的成员(Member)创建对象:Student Lilei; //创建对象Student是类名,liLei是对象名。
和使⽤基本类型定义变量的形式类似, 从这个⾓度考虑,我们可以把 Student 看做⼀种新的数据类型,把 liLei 看做⼀个变量。
在创建对象时,class 关键字可要可不要class Student LiLei; //正确Student LiLei; //同样正确还可以创建对象数组:Student allStu[100];使⽤对象指针:Student stu;//pStu 是⼀个指针,它指向 Student 类型的数据,通过 Student 创建出来的对象Student *pStu = &stu;在堆上创建对象,这个时候就需要使⽤前⾯讲到的new关键字Student *pStu = new Student;使⽤ new 在堆上创建出来的对象是匿名的,没法直接使⽤,必须要⽤⼀个指针指向它,再借助指针来访问它的成员变量或成员函数.对象指针后,可以通过箭头->来访问对象的成员变量和成员函数;两种创建对象的⽅式:⼀种是在栈上创建,形式和定义普通变量类似;另外⼀种是在堆上使⽤ new 关键字创建,必须要⽤⼀个指针指向它,读者要记得 delete 掉不再使⽤的对象C++类的成员变量和成员函数在定义类的时候不能对成员变量赋值,因为类只是⼀种数据类型或者说是⼀种模板,本⾝不占⽤内存空间,⽽变量的值则需要内存来存储.类的成员函数也和普通函数⼀样,都有返回值和参数列表,它与⼀般函数的区别是:成员函数是⼀个类的成员,出现在类体中,它的作⽤范围由类来决定;⽽普通函数是独⽴的,作⽤范围是全局的,或位于某个命名空间内.只在类体中声明函数,⽽将函数定义放在类体外⾯,如下图所⽰:class Student{public://成员变量;char *name;int age;float score;//声明成员函数;void say();};//定义成员函数void Student::say(){cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;}类体内成员函数默认为内联函数; inline 关键词是多余的;类体外定义 inline 函数的⽅式,必须将类的定义和成员函数的定义都放在同⼀个头(源)⽂件中.C++类成员的访问权限以及类的封装成员访问限定符publicprivateprotected只能修饰类的成员,不能修饰类,C++中的类没有共有私有之分类的内部(定义类的代码内部):⽆论成员被声明为 public、protected 还是 private, 都是可以互相访问的,没有访问权限的限制.在类的外部(定义类的代码之外),只能通过对象访问成员,并且通过对象只能访问 public 属性的成员,不能访问 private、protected 属性的成员。
定义函数的几种方法函数是计算机程序中一个独立且可重复使用的代码块。
它可以接受输入参数,并通过执行特定的操作来产生输出结果。
函数是程序设计中的一种基础概念,它将大型程序分解成较小的模块,使得代码更加模块化、易读、易维护。
在不同的编程语言中,定义函数的方式和语法可能会有所不同。
下面是一些常见的函数定义的方法。
1. 函数定义关键字:通过在不同的编程语言中使用特定关键字来定义函数。
例如,在Python中使用`def`关键字来定义函数,形式如下:```pythondef function_name(parameters):#执行代码块return result```其中`function_name`是函数的名称,`parameters`是函数的参数,可以有一个或多个。
`return`关键字用于返回函数的结果。
2. 匿名函数:有些编程语言支持匿名函数的定义方式。
它们也被称为lambda函数。
这种函数没有名称,通常用于简单的操作。
例如,在Python中可以使用以下方式定义匿名函数:```pythonlambda parameters: expression其中`parameters`是函数的参数,可以有一个或多个。
`expression`是函数的操作,执行并返回结果。
3. 方法定义:有些编程语言中,函数被定义在类的内部,被称为方法。
在这种情况下,函数会关联到特定的对象,并可以访问该对象的属性和方法。
方法定义的方式与函数定义类似,但它们是通过类来调用的。
例如,在Python中的方法定义形式如下:```pythonclass ClassName:def method_name(self, parameters):#执行代码块return result```其中`ClassName`是类的名称,`method_name`是方法的名称,`parameters`是方法的参数,可以有一个或多个。
`self`参数表示该方法是对象的一部分。
VBA中的自定义函数和类模块使用方法自定义函数和类模块是 Visual Basic for Applications (VBA) 中的两个重要概念。
它们让我们能够进一步扩展和自定义 Excel 等 Office 应用程序的功能。
本文将介绍如何在 VBA 中使用自定义函数和类模块。
一、自定义函数自定义函数是一种自定义的 VBA 代码,它接受输入参数并返回结果。
通过创建自定义函数,我们可以在 Excel 的单元格中使用这些函数,以便进行特定的计算、操作和数据处理。
1. 创建自定义函数在 VBA 编辑器中,我们可以通过以下步骤创建自定义函数:1. 打开 Excel 并按下 "ALT + F11" 组合键,以打开 VBA 编辑器。
2. 在 VBA 编辑器中,选择所需的工作簿,然后插入一个新的模块。
3. 在模块中编写自定义函数的 VBA 代码。
例如,以下是一个简单的自定义函数,用于计算两个数的和:```vbaFunction Sum(a As Double, b As Double) As DoubleSum = a + bEnd Function```2. 使用自定义函数使用自定义函数时,我们可以在 Excel 的单元格中直接调用它们,就像使用内置函数一样。
在需要的单元格中输入函数名和参数,然后按下回车键即可看到结果。
例如,如果我们在单元格A1中输入"=Sum(1, 2)",按下回车键后,A1的值将变为3,表示1和2的和。
二、类模块类模块是VBA中用于创建自定义对象的模块。
它可以用来定义属于特定类的属性和方法,进一步扩展 VBA 的能力。
通过类模块,我们可以创建属于自己的对象,实现更复杂的逻辑和操作。
1. 创建类模块要创建类模块,请遵循以下步骤:1. 打开 Excel 并按下 "ALT + F11" 组合键,以打开 VBA 编辑器。
2. 在 VBA 编辑器中,选择所需的工作簿,然后插入一个新的类模块。
C++模板编程中只特化模板类的⼀个成员函数模板编程中如果要特化或偏特化(局部特化)⼀个类模板,需要特化该类模板的所有成员函数。
类模板中⼤多数成员函数的功能可能是⼀模⼀样的,特化时我们可能只需要重新实现1、2个成员函数即可。
在这种情况下,如果全部重写该模板类的所有成员函数,不但会增加⼯作量,也不利于代码的维护。
例如下⾯的类模板A,只有在模板参数是char*时才需要特化成员函数func(),但其他的成员函数都不需要特化:1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 void func()8 {9 std::cout << "common type." << std::endl;10 }11 };1213 int main()14 {15 A<int> i;16 i.func();1718 A<char*> c;19 c.func();2021 return 0;22 }⽅法⼀:通过运⾏时类型识别,这个⽅法最简单1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 void func()8 {9 if (typeid(_Ty) == typeid(char*))10 std::cout << "common type." << std::endl;11 else12 std::cout << "special type." << std::endl;13 }14 };⽅法⼆:通过类的成员函数模板特化来实现,这个⽅法也⽐较简单1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 template <typename __Ty>8 void funcImpl()9 {10 std::cout << "common type." << std::endl;11 }1213 template <>14 void funcImpl<char*>()15 {16 std::cout << "special type." << std::endl;17 }1819 void func()20 {21 funcImpl<_Ty>();22 }23 };⽅法三:通过⼀个嵌套模板类的特化来实现1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 template <typename __Ty>8 struct IsCharPType9 {10 const static bool b = false;11 };1213 template<>14 struct IsCharPType<char*>15 {16 const static bool b = true;17 };1819 void func()20 {21 if (IsCharPType<_Ty>::b)22 std::cout << "special type." << std::endl;23 else24 std::cout << "common type." << std::endl;25 }26 };⽅法四:先定义⼀个嵌套的类模板,通过重载函数实现(函数的参数类型不同)1 template <typename _Ty>2 struct A3 {4 // 其他成员函数a5 // 其他成员函数b6 // ......7 template <typename __Ty>8 struct TypeClass9 {10 };1112 template <typename __Ty>13 void funcImpl(const TypeClass<__Ty>&)14 {15 std::cout << "common type." << std::endl;16 }1718 void funcImpl(const TypeClass<char*>&)19 {20 std::cout << "special type." << std::endl;21 }2223 void func()24 {25 funcImpl(TypeClass<_Ty>());26 }27 };。
C++模板详解(⼀)C++模板 模板是C++⽀持参数化多态的⼯具,使⽤模板可以使⽤户为类或者函数声明⼀种⼀般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。
模板是⼀种对类型进⾏参数化的⼯具; 通常有两种形式:函数模板和类模板; 函数模板针对仅参数类型不同的函数; 类模板针对仅数据成员和成员函数类型不同的类。
使⽤模板的⽬的就是能够让程序员编写与类型⽆关的代码。
⽐如编写了⼀个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型⽆法实现,要实现这些类型的交换就要重新编写另⼀个swap函数。
使⽤模板的⽬的就是要让这程序的实现与类型⽆关,⽐如⼀个swap模板函数,即可以实现int 型,⼜可以实现double型的交换。
模板可以应⽤于函数和类。
下⾯分别介绍。
注意:模板的声明或定义只能在全局,命名空间或类范围内进⾏。
即不能在局部范围,函数内进⾏,⽐如不能在main函数中声明或定义⼀个模板。
⼀、函数模板通式1、函数模板的格式: template <class形参名,class形参名,......> 返回类型函数名(参数列表) { 函数体 } 其中template和class是关见字,class可以⽤typename 关见字代替,在这⾥typename 和class没区别,<>括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。
⼀但声明了模板函数就可以⽤模板函数的形参名声明类中的成员变量和成员函数,即可以在该函数中使⽤内置类型的地⽅都可以使⽤模板形参名。
模板形参需要调⽤该模板函数时提供的模板实参来初始化模板形参,⼀旦编译器确定了实际的模板实参类型就称他实例化了函数模板的⼀个实例。
⽐如swap的模板函数形式为 template <class T> void swap(T& a, T& b){},当调⽤这样的模板函数时类型T就会被被调⽤时的类型所代替,⽐如swap(a,b)其中a和b是int 型,这时模板函数swap中的形参T就会被int 所代替,模板函数就变为swap(int &a, int &b)。
竭诚为您提供优质文档/双击可除使用,类,模板,需要,模板,参数列表篇一:函数模板和类模板函数模板和类模板【函数模板】若函数只是参数类型不同,功能完全一样,则可以通过一段通用的、适用于多种不同数据类型的代码来完成这一工作,不禁提高代码的可重用性,还提高了软件的开发效率。
使用函数模板就是为了这一目的。
函数模板的定义形式:template类型名函数名(参数表){函数体定义}所有函数模板的定义都是用关键字tenplate开始的,该关键字之后是使用尖括号括起来的“模板参数表”。
模板参数表由用逗号分隔的模板参数构成。
1.class(或typename)标识符,指明可以接受一个类型参数,这些类型参数代表的是类型,可以是内部类型或自定义类型。
2.“类型说明符”标识符,指明可以接收一个由“类型说明符”所规定的常量作为参数。
3.templateclass标识符,指明可以接收一个类模板名作为参数。
函数模板中声明了类型参数t,表示一种抽象的类型。
当主函数调用该函数时,编译器会一函数模板为样本,生成一个函数,这一过程称为函数模板的实例化,新生成的汗水的防护称为函数模板的一个实例。
模板函数与函数重载模板函数与重载是密切相关的。
从函数模板产生的相关函数都是同名的,编译器用重载的方式调用相应的函数。
另外函数模板本身也课题用多种方式重载。
注意:虽然函数模板的使用形式与函数类似,但二者有本质的区别,这主要表现在以下方面。
i.函数模板本身在编译时不会生成任何目标代码,只有由模板生成的实例会生成目标代码。
ii.被多个源文件引用的函数模板,应当连同喊大叔体一同放入头文件中,而不能像普通函数那样,只将声明放入头文件。
iii.函数指针也只能指向模板实例,而不能指向模板本身。
函数模板应用示例:#includeusingnamespacestd;templatevoidoutputa(constt*array,intcount){}intmain(){cout }return0;运行结果:aarraycontains:12345678barraycontains:1.12.23.34.45.56.67.78.8carraycontains:welcometoseeyou!【类模板】使用类模板使用户可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、返回值或局部变量能取任意类型(包括系统预定义的和用户自定义的)。
群体数据:自定义类型的数据(如结构体、数组)它们都是由多个基本类型组成群体类:按面向对象的方法将数据与操作封装起来组成类群体分为线性群体(元素按位置排列)和非线性群体(不按位置顺序标识)。
关于群体数据,只介绍排序和查找排序需要两种操作:比较两数的大小;调整元素在序列中的位置。
(直接插入排序、直接选择排序、起泡排序方法)查找:在序列中找出特定数据元素。
(顺序查找、折半查找方法)对群体类和群体数据采用模板形式。
函数模板和类模板函数模板和类模板模板可以实现参数多态化,就是将程序所处理的对象(对象中包括数据和函数)的类型进行参数化,使得同一程序可处理多种不同类型的对象。
1、函数模板用一个函数处理多种类型的数据,实现程序的重用性。
函数模板的定义:template<class T>或template<typename T>类型名(即返回值类型)函数名(参数表){函数体}主函数中采用不同的返回值类型或参数类型来调用这个函数模板,实现不同数据类型的输出。
2、类模板使用类模板可以使用户为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值取任意类型。
类是对公共性质的抽象,类模板是对不同类的公共性质的抽象。
类模板声明语法:template <模板参数表>class 类名{类成员声明;}有一点不好,受到限制:各个成员(数据成员、函数成员)中需要变化的类型通常要用到模板的类型参数T。
在类模板以外定义成员函数:(成员函数的实现)template <模板参数表>类型名类名<T>::函数名(参数表){函数体}通常模板参数表是这样的:class T。
类型名为T。
对模板参数表的说明:模板参数表是由逗号分隔的若干类型标识符或者常量表达式构成,内容一般包括下面两个:1、class(或typename)标识符,目的是指明一个类型参数2、类型说明符标识符,目的是指明一个常量参数,这个常量参数是由“类型说明符”规定。
模板类的定义和实现可以分开吗篇一:为什么对于模板不支持分离式编译为什么C++编译器不能支持对模板的分离式编译刘未鹏(pongba)C++的罗浮宫(/pongba)首先,一个编译单元(translation unit)是指一个.cpp 文件以及它所#include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件(假定我们的平台是win32),后者拥有PE (Portable Executable,即windows可执行文件)文件格式,并且本身包含的就已经是二进制码,但是不一定能够执行,因为并不保证其中一定有main函数。
当编译器将一个工程里的所有.cpp文件以分离的方式编译完毕后,再由连接器(linker)进行连接成为一个.exe文件。
举个例子:在这个例子中,test. cpp和main.cpp各自被编译成不同的.obj文件(姑且命名为test.obj和main.obj),在main.cpp中,调用了f函数,(来自: 小龙文档网:模板类的定义和实现可以分开吗)然而当编译器编译main.cpp时,它所仅仅知道的只是main.cpp中所包含的test.h文件中的一个关于void f();的声明,所以,编译器将这里的f看作外部连接类型,即认为它的函数实现代码在另一个.obj文件中,本例也就是test.obj,也就是说,main.obj 中实际没有关于f函数的哪怕一行二进制代码,而这些代码实际存在于test.cpp所编译成的test.obj中。
在main.obj中对f的调用只会生成一行call指令,像这样:在编译时,这个call指令显然是错误的,因为main.obj中并无一行f的实现代码。
那怎么办呢?这就是连接器的任务,连接器负责在其它的.obj中(本例为test.obj)寻找f的实现代码,找到以后将call f这个指令的调用地址换成实际的f 的函数进入点地址。
类模板类模板也称为类属类或类生成类,是为类定义的一种模式,它使类中的一些数据成员和成员函数的参数或返回值可以取任意的数据类型。
类模颁布是一个具体的类,它代表着一族类,是这一族类的统一模式。
使用类模板就是要将它实例化为具体的类。
定义类模板的一般形式为:template<class 数据类型参数标识符>class 类名{//……}其中,template是声明类模板的关键字;template后面的尖括号不能省略;数据类型参数标识符是类模板中参数化的类型名,当实例化类模板时,它将由一个具体的类型来代替。
定义类模板时,可以声明多个类型参数标识符,各标识符之间用逗号分开。
类定义中,凡要采用标准数据类型的数据成员、成员函数的参数或返回类型的前面都要加上类型标识符。
如果类中的成员函数要在类的声明之外定义,则它必须是模板函数。
其定义形式为:template<class 数据类型参数标识符>数据类型参数标识符类名<数据类型参数标识符>∷函数名(数据类型参数标识符形参1,……,数据类型参数标识符形参n){函数体}模板类将类模板的模板参数实例化后生成的具体的类,就是模板类。
由类模板生成模板类的一般形式为:类名<数据类型参数标识符>对象名1,对象名2,…,对象名n;这里的数据类型参数标识符对应的是对象实际需要的数据类型。
6.4 应用举例例6.1 函数模板的声明和模板函数的生成的例。
#include<iostream.h>template<typename T> //声明模板函数,T为数据类型参数标识符void swap(T &x, T &y) //定义模板函数{T z; //变量z可取任意数据类型及模板参数类型Tz=y;y=x;x=z;}void main(){int m=1,n=5;double a=8.9,b=3.4;cout<<”m=”<<m<<”n=“<<n<<endl;cout<<”a=”<<a<<”b=”<<b<<nedl;swap(m,n); //实例化为整型模板函数swap(a,b); //实例化为双精度型模板函数cout<<“m与a,n与b交换以后:”<<endl;cout<<”m=”<<m<<”n=“<<n<<endl;cout<<”a=”<<a<<”b=”<<b<<endl;}程序运行结果:m=1 n=5a=8.9 b=3.4m与a,n与b交换以后:m=5 n=1a=3.4 b=8.9例6.2 类模板的声明和模板类的生成的例。
类模板与模板类详解在C++的Template中很多地⽅都⽤到了typename与class这两个关键字,有时候这两者可以替换,那么这两个关键字是否完全⼀样呢? 事实上class⽤于定义类,在模板引⼊c++后,最初定义模板的⽅法为:template<class T>,这⾥class关键字表明T是⼀个类型,后来为了避免class在这两个地⽅的使⽤可能给⼈带来混淆,所以引⼊了typename这个关键字,它的作⽤同class⼀样表明后⾯的符号为⼀个类型,这样在定义模板的时候可以使⽤下⾯的⽅式了: template<typename T>.在模板定义语法中关键字class与typename的作⽤完全⼀样区分类模板与模板类的概念 ⼀个类模板(类⽣成类)允许⽤户为类定义个⼀种模式,使得类中的某些数据成员、默认成员函数的参数,某些成员函数的返回值,能够取任意类型(包括系统预定义的和⽤户⾃定义的)。
如果⼀个类中的数据成员的数据类型不能确定,或者是某个成员函数的参数或返回值的类型不能确定,就必须将此类声明为模板,它的存在不是代表⼀个具体的、实际的类,⽽是代表⼀类类。
类模板定义:定义⼀个类模板,⼀般有两⽅⾯的内容:A。
⾸先要定义⼀个类,其格式为:template<class T>class test{....}test为类名,在类定义体中,如果采⽤通⽤数据类型的成员,函数参数的前⾯需加上T,其中通⽤类型T可以作为普通成员变量的类型。
还可以作为成员函数的参数和返回类型等。
例如:1 template<class T>23 class Test4 {5 private:6 T n;7 const T i;8 public:9 Test():i(0) {}10 Test(T k);11 ~Test(){}1213 void print();14 T operator+(T x);15 };如果在类外定义成员函数,若此成员函数中有模板参数存在,则除了需要和⼀般类的类外定义成员函数⼀样的定义外,还需要在函数外进⾏模板声明例如:1 template<class T>2 void Test<T>::print()3 {4 std::cout<<"n="<<n<<std::endl;5 std::cout<<"i="<<i<<std::endl;6 }1 template<class T>2 Test<T>::Test(T k):i(k){ n=k;} //构造函数34 template<class T>5 T Test<T>::operator+(T x){6 return n + x;7 }关于类模板的使⽤:类模板的使⽤实际上是将类模板实例化成⼀个具体的类,它的格式为:类名<实际的类型>模板类是类模板实例化后的⼀个产物,说个具体点的例⼦吧,我们把类模板⽐作是⼀个做饼⼲的模⼦,⽽模板类就是⽤这个模⼦做出来的饼⼲,⾄于这个饼⼲是什么味道的就要看你⾃⼰在实例化时⽤的是什么材料了,你可以做巧克⼒饼⼲,也可以做⽜奶饼⼲,这些饼⼲出了材料不⼀样外,其它的东西都是⼀样的了。
C++之模板(T emplate)模板是C++提供进行编程的一种类书工具。
所以在看本文以前请先了解一下C++类书的概念及相关的知识。
1.模板的概念:模办是实现类属机制的一种工具,它的功能非常强,它是无约束类属机制和约束类属机制的集合。
它可以让用户构造模板函数。
模板,对象,函数之间的关系见下图:2.函数模板与模板函数:先见下例:#include <iostream.h>template<class T> //模板声明T max(T x,T y) //定义模板{return (x>y)? x:y;}main(){int i=10,j=56;float x1=50.34, x2=56.34;double y1=673.36, y2=465.972;cout<<"the max of i, j is:"<<max(i, j)<<"\n";cout<<"the max of x1, x2 is:" <<max(x1,x2)<<"\n";cout<<"the max of y1, y2 is:" <<max(y1,y2)<<"\n";return 1;}上面的这个程序虽然只是实现一个很简单的比较大小的问题,但如果不用模板,而用我们以前的方法,由于参数类型和返回值类型不同将需要三个函数来实现,这样是十分麻烦的。
模板成功的解决了这个问题,程序中生成了三个模板函数,其中max(i,j)用模板实参int将类型实参数T进行了实例化;max(x1,x1)用模板实参float将类型参数T进行了实例化;max(y1,y2)用模板实参double将类型参数T进行了实例化。
第06章类和对象1.填空题(1)类和对象是面向对象程序设计的两个最本概念,__表示抽象的概念,而__则是__的实例化。
(2)类的成员包括__和__两类。
(3)类的数据成员__在类的定义时进行初始化。
(能/不能)(4)类成员的访问方式包括__、__和__3种,默认的访问方式是__。
(5)类的__是为类的所有对象所共有的。
(6)类中声明友元的关键是__。
(7)在类的外部定义成员函数时应在函数的前面加上__和__。
(8)访问对象的成员有__、__和__3种格式。
(9)__函数和__函数是类的两种特殊的成员函数。
__函数负责完成对象的创建和初始化工作,__函数负责完成对象消失时的内存清理工作。
(10)类的__成员和__成员需要初始化表的方式提供初值。
(11)类的静态数据成员的初始化应该写在__区域上,而且要指明__和__。
(12)常对象只能调用类中的__函数,该函数为类的__函数。
(13)类的私有成员和保护成员只能被该类的__函数和__函数访问。
(14)C++中的类的成员指针有__指针和__指针。
(15)类的每一个成员函数都有一个隐含定义的指针,称为__指针,它的类型是成员函数所属类的类型。
(16)对象之间成员级的拷贝,称为__,可以采用默认的拷贝的构造函数。
2.选择题(1)下列关于和对象的描述上,不正确的是()。
(A)一个对象只能属于一个类。
(B)对象是类的一个实例。
(C)一个类只能有一个对象。
(D)类和对象的关系与数据类型和变量的关系类似。
(2)若有如下类声明:class A{int a;}则A类的成员a是()。
(A)公有数据成员(B)公有的成员函数(C)私有数据成员(D)私有成员函数(3)下列关于成员函数的描述中,不正确的是()。
(A)成员函数可以重载。
(B)成员函数一定是内联函数(C)成员函数可以是静态的(D)成员函数可以设置参数的默认值(4)在类外定义成员函数时,需要在函数名前加上()。
(A)对象名(B)类名(C)类名和作用域运算符(D)作用域运算符(5)下列关于this指针的描述中,正确的是()。
一、单项选择题1.有以下类的说明,请指出错误的地方_。
class CSample{int a=2. 5;(A)Csample();(B)public:CSample(int val);(C)-CSample();(D)};答:A分析:类的数据成员不能直接赋初值。
2.在C+十中,可以把具有相同内部存储结构和相同操作的对象看成属于同一类。
在指定一个类后,往往把属于这个类的对象称为类的①。
从语言角度来说,类是一种数据类型,而②是具有这种类型的变量。
A.实例B.实物C.特征D.对象答:①A②D3.有关类的说法不正确的是。
A.类是一种用户自定义的数据类型B.只有类中的成员函数才能存取类中的私有数据C.在类中,如果不作特别说明,所有的数据均为私有类型D.在类中,如果不作特别说明,所有的成员函数均为公有类型答:D4.有关类和对象的说法下列不正确的有。
A.对象是类的一个实例B.任何一个对象只能属于一个具体的类C.一个类只能有一个对象D.类与对象的关系和数据类型和变量的关系相似答:C5.有关构造函数的说法不正确的是。
A.构造函数名字和类的名字一样B.构造函数在说明类变量时自动执行C.构造函数无任何函数类型D.构造函数有且只有一个答:D6.有关析构函数的说法不正确的是。
A.析构函数有且只有一个B.析构函数无任何函数类型C.析构函数和构造。
数一样可以有形参D.析构函数的作用是在对象被撤消时收回先前分配的内存空间答:C分析:构造函数可以有形参,但析构函数不能有形参。
7.在类的定义体外定义成员函数时,需要在函数名前加上(1) ,而在域外使用成员函数时,需要在成员名外加上②的名字。
A类标记B.类域标记C.类对象D.域运算符答:①B②C8.若函数是在运行时被激活的,则该函数称为。
A内联函数B.非内联函数C.成员函数D.静态成员函数答:B9.在类的定义形式中,数据成员、成员函数和组成了类定义体。
A.成员的访问控制信息B.公有消息C.私有消息D.保护消息答:A10.的功能是对对象进行初始化。
光盘使用说明使用1.本书1~20章所附代码的运行环境操作系统:Windows 2003、Windows XP Professional,或者Windows 2000开发环境:Microsoft Visual C++ 6,个别代码需要Microsoft VC++ 2005,已说明说明:本书所有代码均严格遵照2003年ISO/ANSI C++标准,读者可不做修改,直接将程序移植到其他开发环境下使用。
2.本书所附光盘范例第1章(\chap1)示例描述:本章演示如何开始使用C++进行程序的开发。
HelloWord 第一个用C++开发的Windows应用程序。
第2章(\chap2)示例描述:本章介绍C++语言的基本语素。
MultiplyTwoNumber 简单示例如何编写两个整数相乘的C++程序。
AnotherMultiply2Number 两数相乘的另一种写法。
DefineA Variable 定义一个变量并对其赋值。
CharSample1 单字符常量和双字符常量的用法。
CharSample2 字符型常量的数值形式。
CharSample3 字符型的算术运算。
Square1 计算边长为4.0的正方形的周长与面积。
Square2 符号常量的声明与使用。
Enum 使用枚举常量。
Arithmetic 算术运算符和算术表达式的用法示例。
Shift 移位运算的用法。
BitLogic 位逻辑运算用法示例。
CompoundAssign 复合赋值运算符的用法。
PrefixAndPostfix 自增/自减运算符的前缀形式和后缀形式。
Comma 逗号表达式的用法。
AssigmentConversion1 赋值转换:较大整型转换为较小整型。
AssigmentConversion2 类型转换:浮点型转换为整型。
AssigmentConversion3 较大的浮点型转换为较小的浮点型AssigmentConversion4 类型转换:整型转换为浮点型。