第十一章 使用类

  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》读书笔记之九—使用类的更多相关文章

  1. C++ Primer Plus读书笔记(九)内存模型和名称空间

    1.作用域和链接 int num3; static int num4; int main() { } void func1() { static int num1; int num2; } 上边的代码 ...

  2. C++ primer plus读书笔记——第13章 类继承

    第13章 类继承 1. 如果购买厂商的C库,除非厂商提供库函数的源代码,否则您将无法根据自己的需求,对函数进行扩展或修改.但如果是类库,只要其提供了类方法的头文件和编译后的代码,仍可以使用库中的类派生 ...

  3. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  4. 《C#从现象到本质》读书笔记(九)第11章C#的数据结构

    <C#从现象到本质>读书笔记(九)第11章C#的数据结构 C#中的数据结构可以分为两类:非泛型数据结构和泛型数据结构. 通常迭代器接口需要实现的方法有:1)hasNext,是否还有下一个元 ...

  5. 《C++ Primer》读书笔记 第一章

    读<C++ Primer>才知道,自己对C++知之甚少... 写个博客记录下自己C++的成长,只是读书笔记,不是对<C++ Primer>知识点的总结,而是对自己在书上看到的以 ...

  6. 《android开发艺术探索》读书笔记(九)--四大组件

    接上篇<android开发艺术探索>读书笔记(八)--WindowManager No1: 四大组件除了BroadcastReceiver,其他三种组件都必须在AndroidManifes ...

  7. C primer plus 读书笔记第一章

    写在前面: 算法和数据结构是计算机学习的基础,而大部分书籍是用C/C++编写.所以有了把C语言重新学一遍的想法.这个系列主要是记录看C primer plus的一些笔记和部分课后习题的答案,不会总结的 ...

  8. 《C++ Primer》读书笔记—第二章 变量和基本类型

    声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.8比特的char类型计算机表示的实际范围是-12 ...

  9. 《C++ Primer》读书笔记—第一章 开始

    声明: 文中内容收集整理自<C++ Primer 中文版 (第5版)>,版权归原书所有. 学习一门程序设计语言最好的方法就是练习编程. 1.一个函数的定义包含四个部分:返回类型(retur ...

随机推荐

  1. HttpClient和HttpGet 参数的优先级

    http://www.cnblogs.com/LBSer/p/3295584.html 一般在使用HttpClient时,我们提前设置好参数,比如超时时间(一般socket超时和连接超时) priva ...

  2. redis实战笔记(6)-第6章 使用 Redis构建应用程序组件

    本章主要内容   1.构建两个前缀匹配自 动补全程序 2.通过构建分布式锁来提高性能 3.通过开发计数信号量来控制并发 4.构建两个不同用途的任务队列 5.通过消息拉取系统来实现延迟消息传递 6.学习 ...

  3. golang基础--细说defer

    defer 匿名函数特性 执行方式类似其它语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行 //执行顺序相反 package main import "fmt" ...

  4. 消息管理-activemq

    1.ConnectionFactory("tcp://192.168.1.103:61616/"); 本机地址192.168.1.103 也 可以是localhost 消息的生产者 ...

  5. WCF异常信息

    1.服务“CJ.Demo.Conso.WcfService.EmployeeMngService”有零个应用程序(非基础结构)终结点.这可能是因为未找到应用程序的配置文件,或者在配置文件中未找到与服务 ...

  6. redis使用场景之位操作(大数据处理)

    在学习redis的过程了,看到了redis还能用于大数据处理,具体场景如下: 腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下 ...

  7. 二十一、curator recipes之TreeCache

    简介 curator的TreeCache允许对某个路径的数据和路径变更以及其下所有子孙节点的数据和路径变更进行监听. 官方文档:http://curator.apache.org/curator-re ...

  8. SpringMVC 面试题

    SpringMVC 面试题 什么是Spring MVC ?简单介绍下你对springMVC的理解? Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring ...

  9. idea 版本升级至最新版

    前言:当前最新版为官网上的2018.2.3版本 一.下载最新版 官网地址:http://www.jetbrains.com/idea/download/#section=windows 百度网盘地址: ...

  10. 一个支持DbFirst、ModelFirst和CodeFirst的数据库小工具DbTool

    DbTool 一个支持DbFirst.ModelFirst和CodeFirst的数据库工具. 简介 这是一个针对 SqlServer 数据库和 C# 开发语言的小工具,可以利用这个小工具生成数据库表对 ...