对象更有用的玻璃罩_第1页
对象更有用的玻璃罩_第2页
对象更有用的玻璃罩_第3页
对象更有用的玻璃罩_第4页
对象更有用的玻璃罩_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、对象更有用的玻璃罩原创案例讲解”玻璃罩 const ”系列的三篇文章: 1. 使用常对象为共用数据加装一个名为 const 的玻璃罩 2. 常( const )+ 对象 + 指针:玻璃罩到底保护哪一个 3. 对 象更有用的玻璃罩常引用本文讲在基于对象的程序设计中,函数中传递参数使用 更广泛的技术,利用引用及常引用的话题。 先从引用的 作用开始谈起。一、引用用在参数传递中的优势:带回修改值及节省开 支 先从一个经典的例子开始。 假如现在要交换两个 整数,编写出的程序如下: cpp view plaincopyprint?/ 程序 1 #include <iostream> using

2、 namespace std; void swap(int x, int y); / 用整形本身做形参 int main() int a=5,b=3; swap(a,b);/ 函数调用时传值cout<<a=<<a<< , b=<<b<<endl; / 输出 a=5,b=3 ,根本不能完成交换值 system(pause); return 0; void swap(int x,int y) int t; t=x; x=y; y=t; 这个程序无法完成任务。 因为在第 9 行调用 swap() 函数时, 将实参 a,b 的值传递给了 实参

3、x,y,函数swap()在执行时,确实也交换了 x和y。但 是,任务最终交换 a 和 b 的要求却不能完成,前述的交换已 经与 a,b 无关。 在传统 C 语言中,可以利用指针实现在 函数中改变实参所对应存储单元的值。 cpp view plaincopyprint?/ 程序 2 #include <iostream>using namespace std; void swap(int *x, int *y); int main() int a=5,b=3; swap(&a,&b); /将 a 和 b 的地址值传递给形式参数 x 和 y cout<<a=

4、<<a<< , b=<<b<<endl; / 将输出 a=3, b=5 ,交换成功 system(pause);return 0; void swap(int *x,int *y) /x 指向 a, y 指向 b int t;t=*x;*x=*y;II对*x 的修改,即是对实参a的修改*y=t;II对*y的修改,即是对实参b 的修改 在将实际参数 a 和 b 的地址值传递给形式 参数 x 和 y 后, swap() 函数中所做出的针对 x 和 y 所指向的 单元的修改,改的就是 a和b的值。函数调用完后,尽管 x 和 y 的生命周期结束,但“交换

5、”的结果却留在了 main() 函数 中。 在 C+ 中,引入了引用类型专门处理此类问题。 cpp view plaincopyprint?II 程序 3 #include <iostream>using namespace std;void swap(int &x, int&y); int main() int a=5,b=3;swap(a,b); IIa 即是 x, b 即是 y cout<<a=<<a<< , b=<<b<<endl;II将输出 a=3, b=5 ,交换成功system(pause);

6、return 0; void swap(int &x,int &y) /x即是 a ,y 即是 b int t; t=x; x=y;/ 对 x 的修改,即是对实参 a 的修改 y=t; /对 y 的修改, 即是对实 参b的修改 在第9行调用函数swap()时,按函数 传值的特点和引用类型的含义,x与a共用存储单元,y与b 共用存储单元, 所以在执行函数 swap 时,对 x 和 y 的修改, 就是对a和b的修改。函数调用完后,x和y的生命周期结 束了,但 a 和 b 显然保存的是交换后的值。略做一个总结,可以发现程序 3中的诸多优势。程序 3与程序 2 相比,都能实现在函数中修

7、改实参对应的值,但在实现中,不 用意识到地址的存在,并且从调用的角度, swap(a,b) 比 swap(&a,&b) 直观、简单的多,这会有效减少程序 中在调用时可能犯的错误。程序 2 中需要两个存储地址值的 单元x和y,而程序3中的x和y直接用的就是a和b的单 元,从空间角度,节省了可能我们并不在意的一点点空间。 程序 3 与程序 1 相比,两者在调用的形式上完全一样,函数 体的写法完全一样,仅是函数原型中有些许差别。但是,程 序 3 之伟大之一在于,可以在函数中对实参的值进行修改, 而程序 1 却不行。另外一个显著区别在于,程序 1 在调用 sway() 时,要为形参分配

8、存储单元,然后将实参的值写入, 而程序 3 中 x 和 y 直接用的就是 a 和 b 的单元, 不用分配空 间,也不用花时间赋值。从本例中,程序 1 的空间多占用 8个字节( x 和 y 分别 4 字节),赋值要多占用一点点时间,这 点空间和时间微不足道。但是,如果形参和实参是对象,并 且数据成员比较多,尤其是某些成员是数组等占用空间很大 时,引用的机制带来的在开支上的节约就不是可以轻言忽略 了。 综上,鉴于可以实现修改的功能,以及在空间、时 间上的巨大优势,可以提高程序的执行效率。当函数参数中 需要涉及对象 (类 )时,我们用引用类型。引用,专为对象而生!二、类对象的引用做形式参数 看一个例

9、子: cpp view plaincopyprint?/ 程序 4 #include <iostream> using namespace std;class Test private:int x; int y; public:Test(int a, intb)x=a;y=b;void printxy() const;voidsetX(int n) x=n; void setY(int n) y=n; ; void Test:printxy() const cout<<x*y=<<x*y<<endl; void doSomething(Test

10、&p1) / 形参是引用类型 p1.setX(5); p1.printxy( ); void main(void) Test t1(3,5); doSomething(t1); / 实参是对象, t1 和 p1 是同义词, p1 占 用的就是 t1 的地址t1.printxy();system(pause); 可以知道,程序执行的结果是输出了两次: x*y=25 。第一次的输出表明,在调用 doSomething() 函数中, t1 的 x 数据成员被修改;而第 2 次 的输出则说明,这个修改确实影响了实参 t1 ,尽管随着程序 调用结束,这种引用关系已经解除。 这是一件令人感到 快意

11、的事。 但,问题由此而生。 如果在需求中, doSomething() 函数确定为不允许修改t1,这种机制不正好成了bug的温床,当程序员无意中错误地写入了诸如第 22 行对数据成员修改 的语句,这种错误将被编译器包庇下来。假如项目灰常大, 那是令人抓狂的后果。 为了限制这种无意的修改,我们 想到了玻璃罩 const 。三、用对象的常引用做形参所谓对象的常引用,就是将引用用 const 进行限定。 自然,引用不能被修改。 将 对象说明为常引用形式是:const 类型名 &对象名 ; 下面是用对象的常引用做形参的例子。 cpp view plaincopyprint?/ 程序 5 #in

12、clude <iostream> using namespace std; class Test private: int x;int y; public:Test(int a, intb)x=a;y=b;void printxy() const;voidsetX(int n) x=n;void setY(int n) y=n; ;/形参是常引用void Test:printxy() const cout<<x*y=<<x*y<<endl; void doSomething(const Test &p1)“Test:setX不能: 将“

13、this 指针从“ const Test 转换为“ Test& p1.printxy( );void main(void)Test t1(3,5);doSomething(t1); / 实参是对象system(pause);第 22 行在编译p1.setX(5); /将招致错误error C2662:时会出现错误,这说明用常引用做形参可以避免函数中对对 象的修改。无论实际参数是否为常对象,这种限制都是存在 的。四、小结 在对象做函数的形式参数时,用对象的引 用做形式参数是一个直观且高效的处理方法,提倡用好。 当不允许在函数体内对参数的值作出修改时,常将形式参数 指定为const,这也是

14、需要用好的 C+的特性。五、玻璃罩系列总结 我将 const 比喻为一个玻璃罩, 由const决定的“常XX的目标就是防止出现不该发生的对变 量/对象的改变,“只许看不许摸”式的限制,成了一个有效的 机制。 下面将限制由严格到更灵活做个排列,也作为对 系列文章的总结。方法示例含义详解链接使用常对象 Test const t1; 或 const Testt1;对象在初始化之后,在任何情况下都不能被修改。这是最严格的限制。(整体任何时候、任何场合都不能改)名为 const 的玻璃罩 类中定义常数据成员 class Testconst int x;Test 类的任一对象,其数据成员 x 均不能被修改

15、;访问 x 的成员函数也必 须为常成员函数。(对象中的某一特定部分在任何时候、任何场合都不能改) 名为 const 的玻璃罩类中定义常成员函数 class Test int x;void f() const;f 函数中,对本类的数据成员, 可以访问,但不可以修改 (在 本函数之外, 随便;但进了本函数所管辖范围, 谁都不要改, 无论是在其他场合可改变的非 const 对象,还是在其他场合 也不能改变的 const 对象。 f 的地盘 f 做主。)名为 const 的玻璃罩函数参数中使用指向常对象的指针作形式参数 void f(const Test *p1, Test *p2) 通过 *p1 访问实参的对象,无论对象是否加了 const 限定,都不可以 被修改。 而在同一个函数中, p2 所指向的对象却是可以被修 改的。(在 f 的地盘上,根据声明区别对待,不该改的别该,该改 的任你改。民主社会的追求。 )用指针避免了函数调用中“大”对象的复制, 可以提高效

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论