第5章 成员函数
自考C++程序设计 总复习

输出一个换行符 清除flag标志位 清除flag标志位 设置ch为填充字符 设置浮点数输出精度 设置输出字符间字段宽度
输出 输出 输出 输出 输出 输出
常量名 Ios_base :: left Ios_base ::right Ios_base ::showpoint Ios_base ::showpos Ios_base ::scientific Ios_base ::fixed
(2)析构函数在对象的生存期结束时被主动调用。类得对象数组的每个元素调用一次构造函 数。 (3)析构函数和运算符delete:当使用delete删除一个动态对象时,它首先为这个动态对象调 用析构函数,然后再释放这个动态对象占用的内存。这和使用new建立动态对象的过程刚好相 反。 5.成员函数重载及默认函数 (1)this指针:c++规定当一个成员函数被调用时,系统自动向它传递一个隐含的参数,该参 数是一个指向调用该函数的指针,从而使成员函数知道该对那个对象进行操作。 (2)this指针是c++实现封装的一种机制,它将该对象调用的成员函数连接在一起,在外部看 来,每一个对象都拥有自己的成员函数。一般情况下都省略符号“this->”,而让系统进行默认 设置。 6.一个类的对象作为另一个类的成员 (1)类本身就是一种新的数据类型,所以一个类可以作为另一个类得成员。
(7)当使用new建立一个动态对象,new首先分配足够对象的内存,然后自动构造函数来初始 化这块内存,再返回这个动态对象的地址。 (8)构造函数的默认参数:如果程序定义自己的有参构造函数,又想使用无参数形式的构造 函数,那么就是吧构造函数使用默认参数设计。 (9)复制构造函数:引用在类中一个很重要的用途是用在复制构造函数中。这一类特殊而且 重要的函数通常用于使自己已有的对象来建立一个新对象。复制构造函数原型如下:类名:: 类名(const 类名 &) 4.析构函数 (1)析构函数析构函数的名称和类名一样,为了与构造函数区分在析构函数前面加~符号。析 构函数不能定义任何返回类型,即使指定为void也不行。一般形式如下:类名::~类名 (void)
C++第5章习题参考答案

1.什么是类的继承与派生?继承性是面向对象程序设计的第二个重要特性,通过继承实现了数据抽象基础上的代码重用。
继承是对许多问题中分层特性的一种自然描述,因而也是类的具体化和被重新利用的一种手段,它所表达的就是一种对象类之间的相交关系。
它使得某类对象可以继承另外一类对象的特征和能力。
继承所具有的作用有两个方面:一方面可以减少代码冗余;另一方面可以通过协调性来减少相互之间的接口和界面。
通过继承方式定义的子类也称为派生类。
2.类的三种继承方式之间的区别是什么?类的继承方式有public(公有)继承、protected(保护)继承和private(私有)继承三种。
对于不同的继承方式,会导致基类成员原来的访问属性在派生类中有所变化。
表5.1列出了不同继承方式下基类成员访问属性的变化情况。
表5.1 不同继承方式下基类成员的访问属性说明:该表第1列给出3种继承方式,第1行给出基类成员的3种访问属性。
其余单元格内容为基类成员在派生类中的访问属性。
从表中可以看出:(1) 基类的私有成员在派生类中均是不可访问的,它只能由基类的成员访问。
(2) 在公有继承方式下,基类中的公有成员和保护成员在派生类中的访问属性不变。
(3) 在保护继承方式下,基类中的公有成员和保护成员在派生类中均为保护的。
(4) 在私有继承方式下,基类中的公有成员和保护成员在派生类中均为私有的。
需要注意的是:保护成员与私有成员唯一的不同是当发生派生后,处在基类protected区的成员可被派生类直接访问,而私有成员在派生类中是不可访问的。
在同一类中私有成员和保护成员的用法完全一样。
3.派生类能否直接访问基类的私有成员?若否,应如何实现?派生类不能直接访问基类的私有成员。
具体实现方式:(1) 在类定义体中增加保护段为了便于派生类的访问,可以将基类私有成员中需提供给派生类访问的部分定义为保护段成员。
保护段成员可以被它的派生类访问,但是对于外界是隐藏起来的。
这样,既方便了派生类的访问,又禁止外界对它的派生类访问。
C++程序设计_郑莉版第五章

globClock;//声明对象globClock, 声明对象globClock Clock globClock;//声明对象globClock, //具有静态生存期 具有静态生存期, //具有静态生存期,文件作用域 //主函数 int main() { //主函数 cout << "First time output:" << endl; //引用具有文件作用域的对象 引用具有文件作用域的对象: //引用具有文件作用域的对象: globClock.showTime();//对象的成员函数具有类作用域 globClock.showTime();//对象的成员函数具有类作用域 globClock.setTime(8,30,30); globClock.setTime(8,30,30); myClock(globClock); Clock myClock(globClock); //声明具有块作用域的对象 声明具有块作用域的对象myClock //声明具有块作用域的对象myClock cout<<"Second time output:"<<endl; myClock.showTime(); //引用具有块作用域的对象 myClock.showTime(); //引用具有块作用域的对象 return 0; }
15
int main() { 静态局部变量,有全局寿命,局部可见。 static int a;// 静态局部变量,有全局寿命,局部可见。 c为局部变量 具有动态生存期。 为局部变量, int b = -10; // b, c为局部变量,具有动态生存期。 int c = 0; "---MAIN-----MAIN---\ cout << "---MAIN---\n"; cout<<" "<<i "<<a "<<b cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl endl; "<<c<<endl; c += 8; other(); cout<<"---MAIN---\ <<"---MAIN--cout<<"---MAIN---\n"; cout<<" "<<i "<<a "<<b cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl endl; "<<c<<endl; i += 10; other(); return 0; }
面向对象程序设计第五章

5.3.3 运算符重载
运算符重载的基本格式: public static 返回值类型 operator 运算符(参数 列表) operator 关键字用来重载运算符,public和 static修饰符为必选项。 public static int operator +(Prime data1,Prime data2)
编译时多态性(静态多态性)在程序编译时就决定如何实现 某一动作,它是通过重载实现的。编译时多态性在编译时就 知道调用方法的全部信息。 运行时多态性(动态多态性)是在程序运行时动态实现某一 动作,它是通过继承和虚方法实现的。
5.3.2 虚方法与重载方法
在定义时加上virtual 修饰符,则该方法就是虚方法。 在派生类中重载虚方法时,要为重载方法加上 override修饰符。 重载虚方法要求派生类的重载方法的方法名称、方法 参数类型、方法参数数量、方法参数顺序和方法返回 值类型都必须与基类中的虚方法完全一样。 在派生类中重载虚方法,将重写从基类继承来的具有 相同名称的虚方法,从而使该方法专用于派生类,为 派生类做具体的工作。 【例5-8】 重载虚方法和重写非虚方法 P117
5.2.2 接口
1. 接口声明 接口声明是一种类型声明,它定义一个新的接口类型。接 口声明格式: 接口修饰符 interface 接口名 : 基接口{ 接口体 } 接口可以包含方法、属性、索引和事件。 接口可以从零或多个接口继承,被继承的接口称为该接口 的显式基接口 public interface IShape { double GetArea(); string Type { get; } }
5.2.2 接口
2. 接口实现 由于接口不提供实现,所以必须使用 类和结构来实现。
西安石油大学大二(上)C++面向对象程序设计课件第5章习题

西安石油大学大二(上)C++面向对象程序设计课件第5章习题习题5基本概念问题:5.1填空:(1)派生类的成员函数可以直接访问基类的成员,不能直接访问基类的______成员。
(2)保护继承时,基类的成员成为派生类中的受保护成员,派生类对象不能直接访问基类成员。
(3)在定义一个派生类时,使用__________关键字或者不显式地使用它则表示为__________继承。
(4)如果在多个基类及其派生类中定义了具有相同名称的成员函数,则在访问相应的函数___________________。
(5)若要保证一个公共的基类在派生类中只产生一个基类子对象,则必须都以____________的方式直接继承它。
5.2多项选择题:(1)从一个基类派生出的各个类的对象之间()。
a、共享所有成员变量,每个对象还包含基类的所有属性。
B.共享一些成员变量,每个对象也包含基类的所有属性。
C.不共享任何成员变量,但每个对象还包含基类的所有属性。
D.共享一些成员变量和成员函数(2)如果是类b在类a的基础上构造,那么,就称()。
a.类a为基类或父类,类b 为超类或子类b、类A是基类、父类或超类,类b是派生类或子类,C.类A是派生类,类b是基类d.类a为派生类或子类,类b为基类、父类或超类(3)c++的继承性允许派生类继承基类的()。
a、部分功能,并允许添加新功能或重新定义基类的功能。
B.部分功能,但不允许添加新功能或重新定义基类的功能。
C.所有特性,并允许添加新特性或重新定义基类的特性。
D.所有特性,但不允许添加新特性或重新定义基类的特性。
(4)派生类的成员函数可以直接访问基类的()成员。
a.所有b.公有和保护c.保护和私有d.私有(5)对于公有继承,基类的公有和保护成员在派生类中将()成员。
a.全部变成公有b.全部变成保护c、 D.保持公共并相应地受到保护(7)对于公共继承,基类中的私有成员将()保留在派生类中。
a.能够直接使用成员名访问b.能够通过成员运算符访问一百三十六c.仍然是基类的私有成员d.变为派生类的私有成员(8)保护继承时,基类的()将成为派生类中的受保护成员。
C语言完整函数教程PPT课件

12
5.1 子程序设计 5.2 函数
5.2.1 函数 5.2.2 函数的定义 5.2.3 函数的调用 5.2.4 函数原型 5.3 头文件 5.4 函数应用举例 5.5 变量作用域 5.6 变量的存储类别 5.7 内部函数和外部函数
printf("%d\t",i);
【程序演示】
16
5.2.2 函数的定义
/*函数功能:判断n是否是闰年 参数: year :要判断的年份 返回值:若是闰年,返回1,否则返回0*/
int isLeapYear(int year) {
if ( (year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0) return 1;
else return 0;
}
17
5.2.2 函数的定义
常见的程序设计错误: (1)把同一种类型的参数声明为类似于形式
float x,y,而不是float x,float y; (2)在函数内部把函数参数再次定义成局部变
量是一种语法错误;如: int sum(int x, int y) {
int x, y;//错误! return (x+y); }
18
5.2.2 函数的定义
(3)不能在一个C函数的内部定义另一个函数;
main()
{
…
int sum(int x,int y)
{ return(x+y);
不允许!
}
…
}
19
5.2.2 函数的定义
C++实操之内联成员函数介绍
C++实操之内联成员函数介绍⽬录前⾔什么是内联函数:如何使⼀个函数成为内联:为什么使⽤内联:优点 :缺点 :关键点:总结前⾔在C语⾔中,我们使⽤了宏函数,这是编译器⽤来减少执⾏时间的⼀种优化技术。
那么问题来了,在C++中,有什么更好的⽅法来解决这个问题呢?我们引⼊了内联函数,这是编译器⽤来减少执⾏时间的⼀种优化技术。
我们将讨论内联函数的 “what, why, when & how”。
什么是内联函数:内联函数是C++的⼀个增强功能,可以减少程序的执⾏时间。
函数可以通过指⽰编译器,使其成为内联函数,这样编译器就可以取代那些被调⽤的函数定义。
编译器会在编译时替换内联函数的定义,⽽不是在运⾏时引⽤函数定义。
注意:这只是建议编译器将函数内联,如果函数很⼤(在可执⾏指令等⽅⾯),编译器可以忽略 "内联 "请求,将函数作为普通函数处理。
如何使⼀个函数成为内联:要使任何函数成为内联函数,在其定义的开头使⽤关键字 "inline"。
例⼦:第⼀种情况:class A{public:inline int add(int a, int b){return (a+b);}};第⼆种情况:class A{public:int add(int a, int b);};inline int A::add(int a, int b){return (a+b);}第三种情况:inline int add_two (int a, int b){return (a+b);}你可以在它的类定义中定义⼀个成员函数,或者如果你已经在类定义中声明了(但没有定义)该成员函数,你可以在外⾯定义它。
第⼀种情况:当在类成员列表中定义的成员函数默认为内联成员函数,所以第⼀个class A定义⾥,也可以省略inline关键字。
⼀般含有⼏⾏代码的成员函数通常被内联声明,或者说可以在类的定义中定义较短的函数。
面向对象程序设计教案
面向对象程序设计教案第一章计算机与程序设计基本内容:1.把程序及其相关文档资料称为软件。
2.程序设计语言是人类用来向计算机传递信息的表示方法、约定和规则的集合。
3.传统的程序设计语言是过程性语言,使用这类语言编制程序的主要工作,是设计解题过程,因此称为面向过程程序设计。
4.用模块化、抽象、信息隐藏、局部化和模块化独立等原理及结构程序设计技术指导面向过程程序设计,能够提高软件开发效率,增加软件的可理解性和可维护性。
这些方法不仅适用于面向过程程序设计也适用于面向对象程序设计方法。
5.面向对象方法有四个要点,只有同时使用对象、类、继承和消息的方法,才是真正的面向对象方法。
学习面向对象程序设计,首先要学会面向对象的思维解题方法。
各种面向对象的程序设计语言,无非是实现面向对象解题方法的工具。
6.面向对象方法的主要优点是,接近人类习惯的思维方法、稳定性好、可重用性好和可维护性好。
是解决软件开发面临的难题的最有希望最有前途的方法之一。
1.1 计算机的基本结构1.2 程序设计语言一、机器语言(machine language):以0和1表示手工操作二、汇编语言(assembler language):例如mov ax,100add ax,bx等开始使用批处理(batch processing)三、高级语言(high-level language):如60年代的ALGOL四、结构化程序设计(structured programming)整个程序是一个模块层次(hierarchy of modules)每一模块内既有数据,又有代码,用于按一定算法对代码进行操作如FORTRAN,C等五、面向对象的程序设计(Object-Oriented Programming, OOP)1.3 面向过程程序设计三种基本结构:1、顺序结构。
2、选择结构。
3、循环结构:当型循环结构;直到型循环结构。
结构化程序设计方法:1、自顶而下;2、逐步细化;3、模块化设计;4、结构化编码。
c++教程第5章
§5.1.1 指针的运算
关系运算
可对两相同类的指针进行各种关系运算。 px<py • px所指位置在py之前。 px!=0
• px是否为空指针
注:不同类型指针间,以及指针和一般整 数间进行的关系运算是无意义的。
§5.1.1 指针的运算
赋值运算
向指针变量赋值时,赋的值必须是地址常量或 变量,而不能是普通整数。 例1:char c, *pc; pc=&c; 例2: int *p, *q; p=q; 例3:char name[20], *pname; pname=name; int *p, *q, n; p=q+n;
§5.3 指针和函数
函数指针
函数的入口地址赋给某一指针。 存储类型 数据类型(* 函数指针名)(参数表) 例: int (*fp)(char)
注意 1. 函数指针指向的是程序代码区; 2. 函数指针的参数和返回值与要指向的函数正好匹配; 3. 不能把函数当作参数传递,但可以传递函数指针; 4. 任何类型的指针都可以赋给void*。
§5.4.2 指针和引用
引用是借助于指针来实现的。引用是一种特殊的指 针常量。 指针常量初始化后,就不能再指向别的地址。 指针常量的地址是只读的,读此地址的目的是访问 地址下的对象。所以地址本身不重要。 改变指针常量的含义,使它不再代表地址,而是地 址下的对象,指针常量就变成了引用。 有了指针后,为什么还要引入引用呢?
§5.1.1 指针的运算 算术运算
int *px, *py; px+3, py-3, px-py, *++px, *py- px±n 指针从当前位置向前或向后移动n个数据单位 px±n*sizeof(T) px-py 两指针位置之间的数据个数: (px-py)/sizeof(T) y=*px++与y=(*px)++
C++程序设计04737 第5章 类的继承与派生
5.1 类的继承与类的派生
5.1.2 派生类的定义与大小
2.类的大小
1. //[程序5-2]基类与子类占用空间及字节对齐
2. #include <iostream>
3. using namespace std;
4. class BaseClass //基类
5. {
6.
int v1, v2;
7.
派生类中包含了基类的成员变量,且基类
成员变量在前,派生类成员变量在后。基 类占用了12个字节,在此之后要分配派生 类自身的成员变量,一个int型变量和一个 指针变量。在64位系统中,指针占8个字 节。所以派生类的大小=12+4+8=24字节。 32位系统中指针的大小是4字节。
5.1 类的继承与类的派生
5.1 类的继承与类的派生
5.1.3 继承关系的特殊性
//[程序5-3]派生类继承了友元函数
#include <iostream>
using namespace std;
class another;//前向引用声明
class Base//基类
{private: float x;
public: void print(const another &K);};
d.print(ano);//输出: Base: 100
return 0;
}
如果派生类Derived中重写了print(),若还想在函数中访问another的私有成员,则必须将类Derived的print()函数也
声明为another的友元。在类another中需要添加如下声明:
friend void Derived::print(const another &K);//派生类的成员函数声明为本类的友元
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
关于内联函数的说明 不允许在内联函数内使用循环和开关语句 内联函数的定义必须出现在第一次调用它 之前
所有在类体内定义的函数都是内联函数
11
5.3运算符和表达式
运算符及运算符优先级 什么叫运算符 运算符是连接参加运算的数据的符号,不 同的运算符规定了不同的运算方法和不同 的运算规则 运算符的优先级
16
显式类型转换 显式类型转换的方法有两种。 (1) 强制转换法
强制转换法的格式为:(类型名)(表达式); 如: (2) 函数法 函数法的转换格式为:类型名(表达式); 如: int( x );
17
(int)x;
5.4控制结构
三种基本结构:
顺序结构
是指程序语句按顺序,自上而下依次执行
访问静态成员函数的方法
类名::静态成员函数名
对象名.静态成员函数名 对象指针->静态成员函数名 main() { Myclass m1; Myclass::f(m1 ); }
30
void f2( int *A, int n ) //形参用指针 { for(int i=0;i<n;i++) { if( *( A + i )< 0 ) { *( A + i )= 0; } } } void main() { int a[4] = { 1, -5, 4, -3 }; int n = 4; f2( a, 4); //调用时实参只写数组名 }
1.直接引用的
类中的静态数据成员; 全局数据变量; 用const关键字说明的常量; 2. 间接引用的 类中的非静态数据成员,可以通过该类的对象 间接引用。
37
例如: int ex = 6; const int cx = 7; class Myclass { public: int x; //非静态数据成员 static int y; //静态数据成员 static int f ( Myclass m ); //静态成员函数 }; int Myclass::y = 8; int Myclass::f ( Myclass m ) { m.x = 9; return y + ex + cx + m.x; }
5.6.3函数的参数带缺省值的情况
C++语言允许在函数的原型中(若没有 说明函数的原型,则应在函数定义时)
给一个或多个参数指定默认值。
32
几点说明:
1、在指定了默认值的参数右边不能出现没 有指定默认值的参数。
正确的带缺省值函数的原型是: void f_a ( int x, int y=8, int z = 9) ; 错误的带缺省值函数的原型是: void f_a ( int x=5, int y, int z=6 ) ;× void f_a ( int x=5, int y=6, int z ) ;×
27
二义性的例子:
int f_add( int x, int y, int z ) { return x + y + z;} void main() { int x=5, y=6, z=7,c; c = f_add( ++x, x+y+z, --z ); }
6 5+6+6=17 6 6+6+7=19
12
表达式
什么叫表达式? 用运算符将运算对象(也称操作数)连接起来的、 符合语法规则的式子。 表达式的分类 根据连接符(运算符)的不同,大体上可以将表 达式分为四种: 算术运算表达式 逻辑运算表达式 赋值运算表达式 逗号运算表达式
13
四种表达式:
算术运算表达式(运算结果是数值 )a+b
选择结构(又称分支结构)
是指能根据选择条件,改变程序走向的一种语句
循环结构
根据循环条件,重复执行某段程序的一种语句
18
5.5函数参数的传递机制
传递机制指的是将实参的值传递给形参
C++的传递机制 值传递 (值调用) 引用传递(引用调用) 传地址调用
传值调用
19
5.5.1传值调用的特点 传值调用的实现机制 是系统将实参拷贝一个副本给形参。 实参可以是常量、变量值或表达式 形参为一般变量或类对象变量 注意: 在被调用函数中,形参可以改变,但不影 响实参的值。
第5章 成员函数
内容回顾
1 2 3
数据类型 const数据成员 静态数据成员 动态数据成员
ቤተ መጻሕፍቲ ባይዱ
4
2
本章主要内容 1 成员函数的概念 成员函数的定义与调用 运算符、表达式和控制结构
2
3 4 5 6 7
函数的参数和函数参数的传递机制 静态成员函数
函数的重载
构造函数和析构函数
3
要求
熟悉成员函数的定义和使用 掌握函数参数的传递机制 掌握静态成员函数和重载函数的使用
逻辑运算表达式(运算结果是逻辑值 ) x<y&&8>4 赋值运算表达式(结合性是从右向左的 ) a=20 逗号运算表达式(表达式的值是最后一个 表达式的值 )a++,a*4,a- 14
数据类型的转换
什么类型转换
就是将一种类型的值转换为另一种类型的值。
类型转换有两种形式
隐式类型转换 显式类型转换
5.5.3引用调用的特点
回顾一下引用的主要用途
作为函数的形参
作为函数的返回值
实参为变量名 形参为引用 注意:
实质上直接通过引用来改变实参的值,其实是 起到了传址调用的作用,但它却来的更方便。
24
示例:形参为引用的调用。
#include <iostream.h> void swap(int& x,int& y) { // 定义函数,形参为引用 int temp; temp=x; a b 2 x=y; 2 1 1 y=temp; temp 1 x y } void main( ) { int a=1,b=2; // 定义变量 cout<<"Before Swap a="<<a<<",b="<<b<<endl; swap(a,b); // 引用调用 cout<<"After Swap a="<<a<<",b="<<b<<endl; }
33
2、C++不允许在函数原型和函数定义中,
同时指定默认值。 3、在函数调用时,编译器按从左到右的 顺序将实参传给形参,当实参的数目不足 时,编译器将用默认值来补充所缺少的实
参。
34
示例:带默认参数的函数。
#include <iostream.h> void sum(int x,int y=10) // 带默认参数函数的定义 { cout<<"sum is:"<<x+y<<endl; } void main() { int a=5,b=6; sum(8); //使用默认值10,sum(8,10); sum(a); // 使用默认值10,sum(5,10); sum(a,b);//sum(5,6); }
成员函数的定义
必须具备4个条件 有返回值 有函数名 有形参列表 有函数体 构成函数的原型
6
函数原型的一般形式:
返回值类型 函数名(参数类型1 参数名1,参数类型2 参数名2,…);
返回值类型 函数名(参数类型1 ,参数类型2 ,…);
函数定义的位置:
对于代码较少的成员函数,可以在类内进行
精通构造函数的使用
4
5.1成员函数的概念
什么叫成员函数?
为了实现对象的行为,我们把完成特定功 能的语句组织成小块程序,并注明相应的 名称,这种形式的组合就构成了成员函数。 应该将对象的行为划分的比较细致。 如何达到函数共用的目的: 库函数 全局函数
5
5.2成员函数的定义与调用
28
5.6.2数组作为函数参数的情况 数组作为参数有两种情况 形参用数组,实参用数组名 机制是形参和实参共用内存中的同一个数组。
形参用指针,实参用数组名
机制是实参把数组的名字传递给形参。
29
例如:将数组A[m]中小于0的数改写为0; void f( int A[ ], int n ) //形参用数组 { for(int i=0;i<n;i++) { if( A[i] < 0 ) A[i]= 0; } } void main() { int a[4] = { 1, -5, 4, -3 }; int n = 4; f( a, 4);//调用时实参只写数组名 } 结果是a中的元素变为:1,0,4,0
{return x;}
8
成员函数的调用
一般形式有两种: main() 对象名 . 函数名(实参1,实参2,…); { 对象指针→函数名(实参1,实参2,…); Location l1; 关于形参和实参说明 Location *p; 在定义函数时说明的形参不占内存,只有在函
L1.GetX(); 数调用时形参才被分配内存。
5.6函数的参数
函数参数的求值顺序 数组作为函数参数
带缺省值的函数
26
5.6.1函数参数的求值顺序 C++语言没有规定在函数调用时对实参的 求值的顺序,编译器根据对代码进行优化 的需要自行决定对实参的求值顺序。
如果实参表达 式中的前后变 量相关时会怎 样?
就可能由于求值 顺序的不同产生 二义性。
对于代码较多的成员函数,我们通常在类中进行原