《C++ Primer Plus》读书笔记之九—使用类
第十一章 使用类
1、操作符函数的格式:operator op(argument-list)。op是将要重载的操作符。
2、操作符重载函数的两种调用方式:①函数表示法:C=A.operator+(B);A、B、C都是类对;②操作符表示法:C=A+ B;操作符左侧的对象A是调用对象,操作符右边的对象B是作为参数被传递的对象。
3、不要返回指向局部变量或临时对象的引用,函数执行完毕后,局部变量和临时对象将消失,引用将指向不存在的数据。
4、C++对用户定义的操作符重载的限制:①重载的操作符不必是成员函数,但必须至少有一个操作数是用户定义的类型。这将防止用户为标准类型重载操作符。②使用操作符时不能违反操作符原来的句法规则,不能修改操作符的优先级。③不能定义新的操作符。④不能重载下面的操作符:(sizeof)、(.)、(.*)、(::)、(?:)、typeid、const_cast、dynamic_cast、reiniterpret_cast、static_cast。⑤下面的操作符只能通过成员函数进行重载:(=赋值操作符)、(()函数调用操作符)、([]下标操作符)、(->)。
5、注意:重载的成员函数操作符,左侧的操作数是调用对象。
6、非成员函数,不是由对象调用的,它使用的所有值(包括类对象)都是显式参数。但是,如果函数对类对象有所操作,非成员函数不能直接访问类的私有成员。这时候,需要一类特殊的函数——友元函数。
7、友元函数:将原型放在类声明中,并在原型声明前加上关键字friend:①友元函数不是成员函数,因此不能使用成员操作符来调用。②虽然友元函数不是成员函数,但它与成员函数的访问权限相同。注意:编写友元函数定义时,不要使用类作用域限定符(classname::),不要在定义中使用关键字friend。
8、如果要为类重载操作符,并将非类的项作为第一个操作数,则可以用友元函数来反转操作数的顺序,因为第一个操作数必须为类对象。
9、cout是一个ostream对象,它是智能的,能够识别所有的C++基本类型。这是因为对于每种基本类型,ostream类声明中都包含了相应的重载的operator<<()定义。
10、如果想要用cout输出一个类对象的值,可以通过在类中声明一个友元函数来重载operator<<()函数,如下:
ostream & operator<< (ostream & os,const Time & t)
{
os<<t.hours<<t.minutes;
return os;
}
那么,Time trip;cout<<trip;被转化成operator<<(cout,trip);
11、对于很多操作符来说,可以选择使用成员函数或非成员函数来实现操作符重载。一般来说,非成员函数应是友元函数,这样它才能直接访问私有数据。
12、记住:非成员版本的重载操作符函数所需的形参数目与操作符使用的操作数目相同;而成员版本所需的参数数目少一个,因为其中的一个操作数是通过this指针被隐式的传递的调用对象。
13、对于两个Time类对象T2、T3,求T1=T2+T3;可以用两种格式实现,如下。但要注意:不能同时选择这两种格式,因为这两种格式都与同一个表达式匹配,同时定义这两种格式将被视为二义性错误,导致编译错误。
T1=T2.operator+(T3); // 成员函数
T1=operator+(T2,T3); // 非成员函数(友元)
14、因为操作符是通过函数是实现的,所以只要操作符函数的特征标相同,使用的操作符数量与相应的内置C++操作符相同,就可以多次重载同一个操作符。
15、将一个标准类型变量的值赋给另一种标准类型的变量时,如果这两种类型兼容,则C++自动将这个值转换为接收变量的类型。 C++语言不自动转换不兼容的类型(例如:int *p=10;非法,不过可以强制类型转换:int *p=(int*)10;)。
16、C++允许指定在类和基本类型之间进行转换的方式。首先,任何接受唯一一个参数的构造函数都可被用作转换函数,将类型与该参数相同的值转换为类。如果将类型与该参数相同的值赋给对象,则C++将自动调用该构造函数。例如:有类Stonewt,则Stonewt mycat;mycat=19.6;程序将使用构造函数Stonewt(double)来创建一个临时的Stonewt对象,并将19.6作为初始值。随后,采用逐成员赋值方式将该临时对象的内容复制到mycat中。这一过程称为隐式转换。不过,如果该构造函数的声明前加上了关键字explicit,则该构造函数不能用于这种隐式转换,只能用于显式转换:mycat=Stonewt(19.6);
17、何时使用Stonewt(double)进行隐式转换呢?
①将Stonewt对象初始化为double值时。
②将double值赋给Stonewt对象时。
③将double值传递给接受Stonewt参数时。
④返回值被声明为Stonewt的函数试图返回一个double值时。
⑤在上述任一种情况下,使用可转换为double类型的内置类型时(先将内置类型转换成double,再调用构造函数)。
18、Stonewt mycat=19.6等价于:①Stonewt mycat(19.6);②Stonewt mycat=Stonewt(19.6);不过后两种格式可用于接受多个参数的构造函数。
19、构造函数只用于从某种类型到类类型的转化,要进行相反的转换(即将类转换成某种类型),必须使用特殊的C++操作符函数——转换函数。转换函数是用户定义的强制类型转换。
20、对于转换函数,注意以下几点:①转换函数必须是类方法。②转换函数不能指定返回类型。③转换函数不能有参数。具体的格式为:
operator typename();例如转换为double类型的函数原型为:operator double();注:转换函数是类方法意味着:它需要通过类对象来调用,从而告知函数要转换的值。因此,函数不需要参数。
21、转换函数的隐式转换:double mycat1=mycat;如果只定义了double转换函数,因此不存在二义性,但是如果定义了int和double两个转换函数operator double();和operator int();则该语句long mycat2=mycat;有二义性而被拒绝!因为int和double值都能赋给long值,所以编译器认为使用任意一个转换函数都是合法的。但是如果删除了其中一个,编译器将接受该语句。
22、当类定义了两种或多种的转换时,仍可以用显式强制类型转换来指出使用哪个转换函数:long mycat2=(double)mycat;或者long mycat2=int(mycat);
23、实现加法时的选择:比如要将double量(或者其他内置类型)和Stonewt (类对象)量相加,有两种选择:
①将operator + (const Stonewt&,const Stonewt&)定义为友元函数,让Stonewt(double)构造函数将double类型的参数转换为Stonewt类型的参数。
②将加法操作符重载为一个显式使用double类型参数的函数:Ⅰ、Stonewt operator +(double X);//成员函数 Ⅱ 、friend Stonewt operator+(double X,Stonewt & s); // 友元函数
优缺点:第一种方法依赖于隐式转换,使程序更简短,因为定义的函数较少。缺点是每次转换时,都将调用转换构造函数,增加时间和内存开销。第二种方法(增加一个显式的匹配类型的函数)则刚好相反。它使程序更长,但运行速度较快。
《C++ Primer Plus》读书笔记之九—使用类的更多相关文章
- C++ Primer Plus读书笔记(九)内存模型和名称空间
1.作用域和链接 int num3; static int num4; int main() { } void func1() { static int num1; int num2; } 上边的代码 ...
- C++ primer plus读书笔记——第13章 类继承
第13章 类继承 1. 如果购买厂商的C库,除非厂商提供库函数的源代码,否则您将无法根据自己的需求,对函数进行扩展或修改.但如果是类库,只要其提供了类方法的头文件和编译后的代码,仍可以使用库中的类派生 ...
- C++ primer plus读书笔记——第12章 类和动态内存分配
第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...
- 《C#从现象到本质》读书笔记(九)第11章C#的数据结构
<C#从现象到本质>读书笔记(九)第11章C#的数据结构 C#中的数据结构可以分为两类:非泛型数据结构和泛型数据结构. 通常迭代器接口需要实现的方法有:1)hasNext,是否还有下一个元 ...
- 《C++ Primer》读书笔记 第一章
读<C++ Primer>才知道,自己对C++知之甚少... 写个博客记录下自己C++的成长,只是读书笔记,不是对<C++ Primer>知识点的总结,而是对自己在书上看到的以 ...
- 《android开发艺术探索》读书笔记(九)--四大组件
接上篇<android开发艺术探索>读书笔记(八)--WindowManager No1: 四大组件除了BroadcastReceiver,其他三种组件都必须在AndroidManifes ...
- C primer plus 读书笔记第一章
写在前面: 算法和数据结构是计算机学习的基础,而大部分书籍是用C/C++编写.所以有了把C语言重新学一遍的想法.这个系列主要是记录看C primer plus的一些笔记和部分课后习题的答案,不会总结的 ...
- 《C++ Primer》读书笔记—第二章 变量和基本类型
声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.8比特的char类型计算机表示的实际范围是-12 ...
- 《C++ Primer》读书笔记—第一章 开始
声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.一个函数的定义包含四个部分:返回类型(retur ...
随机推荐
- PTA (Advanced Level) 1021 Deepest Root
Deepest Root A graph which is connected and acyclic can be considered a tree. The hight of the tree ...
- 浅析人脸检测之Haar分类器方法:Haar特征、积分图、 AdaBoost 、级联
浅析人脸检测之Haar分类器方法 一.Haar分类器的前世今生 人脸检测属于计算机视觉的范畴,早期人们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,后来在复杂背景下的人脸检测需求越来越大,人脸 ...
- JVM之---Java源码编译机制
Sun JDK中采用javac将Java源码编译为class文件,这个过程包含三个步骤: 1.分析和输入到符号表(Parse and Enter) Parse过程所做的工作有词法和语法分 ...
- node.js(http协议)
七层网络协议 应用层:浏览器(http,FTP,DNS,SMTP,TeInet)(邓哥)表示层:加密,格式转换(怕别人偷看,加密摩斯电码)会话层:解除或者建立和其他节点的联系(邓哥在想追这个女孩,不再 ...
- Yii 之widget
默认情况下, widget 的视图文件位于包含了widget文件的 views 子目录之下.这些视图可以通过调用 CWidget::render()渲染,这一点和控制器很相似.唯一不同的是,widge ...
- HTML5之新增的属性和废除的属性 (声明:内容节选自《HTML 5从入门到精通》)
新增的属性 1.表单相关的属性 ———————————————————————————————————————————————————————— •autocomplete 属性 autocomple ...
- JQuery和原生JavaScript实现网页定位导航特效
慕课网的一个小课程,练习了一遍,不足之处,欢迎指正(照片在本地,大家可以着重看代码哈): <!DOCTYPE html> <html lang="en"> ...
- 图片加载库Glide的封装工具类,方便以后使用
直接上源码.注释得已经很清晰了,直接调用即可. package com.liuguilin.lovewallpaper.utils; /* * Created by 火龙裸先生 on 2017/3/3 ...
- Android 应用安装
DDMS下Files Explorer /data/app/xxx.apk 安装过程:1.拷贝文件xxx.apk到/data/app/xxx-1.apk 2.在/data/data目录下创建一个文件夹 ...
- 五种常用web服务器jvm参数设置
一.tomcat Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大.有以下几种方法可以选用:第一种方法:在配置文件中设置Windows下,在文件/bi ...