《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 ...
随机推荐
- NodeJS调用jar包
我们在实际的生产.开发实践中,其实要和许多第三方服务商进行打交道,这其中包括使用他们提供的批量与联机服务,但与别的互联网企业不大相同的是,银行作为传统企业,其一贯重视安全性,许多在互联网企业看似理所当 ...
- MySQL中You can't specify target table for update in FROM clause异常
mysql中You can't specify target table <tbl> for update in FROM clause错误的意思是说,不能先select出同一表中的某些值 ...
- Asterist搭建步骤
环境: # cat /proc/version Linux version 2.6.18-308.el5 (mockbuild@x86-010.build.bos.redhat.com) (gcc v ...
- c#基础学习(0806)之StringBuilder的使用
以前字符串的拼接基本都是用string来完成的,从来没有考虑过性能或者速度的问题,自从学习了StringBuilder之后才发现两者的差距有多大,当然,数据量比较小的时候,用string还是挺方便的, ...
- Jsp&Servlet入门级项目全程实录第5讲
惯例广告一发,对于初学真,真的很有用www.java1234.com,去试试吧! 1.修改功能实现 dao public int gradeAdd(Connection con,Grade grade ...
- [C#]INI文件控制类
INI文件常用于保存各类设置或本地化文本,大概格式如下: [Section] key=value 然而.NET框架似乎并没有提供一个实用的工具来操作它,或许是因为MS想让我们都使用Settings类控 ...
- JVM内存问题定位
一.查看机器资源使用状态: 使用top命令,内存占用较高的那个PID对应的进程一般就是JVM了 二.查看Swap状态: 使用free -m 命令,一般内存占用过高会导致swap占用也偏高,看看swap ...
- Java - String, Stringbuilder, StringBuffer比较
http://www.cnblogs.com/zuoxiaolong/p/lang1.html
- 用python写桌面天气预报,自己的学习曲线。
自从接触python,就被他优雅而简洁的代码所吸引. 举个例子: arr , , , , , , , , , , , , , ] ] 如果用其他语言来写的吗,不会这么简洁,美观. python还有 ...
- tr,td高度不生效
功能:表格内容较长,但是页面高度有限,超出显示滚动条 阻碍:给tr或者td加高度都不生效,不显示滚动条 解决方案:td中加div,设置高度和内容溢出时的样式 <table border='1' ...