第11章 使用类

1. 运算符重载是一种形式的C++多态。

2. 不要返回指向局部变量或临时对象的引用。函数执行完毕后,局部变量和临时对象将消失,引用将指向不存在的数据。

3. 运算符重载的格式如下:

operatorop(argument-list);

可以使用函数表示法或运算符表示法来使用它。

total = coding + fixing;

total = coding.operator+(fixing);

4. 运算符重载的限制:

1)  重载后的运算符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载运算符。

2)  使用运算符时不能违法运算符原来的句法规则。例如,操作数个数不能变,不能修改运算符的优先级。

3)  不能创建新运算符。例如,不能定义operaor**()函数来求幂。

4)  不能重载下面的运算符。

sizeof

.(成员运算符)

.*(成员指针运算符)

::

?:

typeid(一个RTTI运算符)

const_cast强制类型转换运算符

dynamic_cast强制类型转换运算符

reinterpret_cast强制类型转换运算符

static_cast强制类型转换运算符

5)  大多数的运算符可以通过成员或非成员函数的进行重载,但下面的运算符只能通过成员函数进行重载。

=赋值运算符

()函数运算符

[]下标运算符

->通过指针访问类成员的运算符

5. 友元有三种:

友元函数

友元类

友元成员函数

  1. 6.  友元函数虽然是在类中声明的,但它不是类的成员函数,因此不能使用成员运算符来调用。友元函数虽然不是类的成员函数,但它与成员函数的访问权限相同。

7. 创建友元

1)  将原型放在类声明中,并在原型声明前加上关键字friend

friend Time operator*(double m, const Time & t);

2)  编写函数定义。因为它不是成员函数,所以不要使用Time::限定符。另外,不要在定义中使用关键字friend。

Time operator*(double m, const Time &t)

{

}

8. 只有类声明可以决定哪一个函数是友元,因此类声明仍然控制了哪些函数可以访问私有数据。总之,类方法和友元只是表达类接口的两种不同机制。

9. 类继承属性使得ostream引用能够指向ostream对象和ofstream对象。

10. 一般来说,要重载<<运算符来显示c_name的对象,可使用一个友元函数,其声明如下:

friend ostream & operator<<(ostream & os, const c_name & obj);

11. 重载运算符:作为成员函数还是友元函数(非成员函数)

对于某些运算符来说,成员函数是唯一合法的选择。在其他情况下,这两种格式没有太大的区别。有时,根据类设计,使用非成员函数版本可能更好(尤其是为类定义类型转换时)。

12. 想返回一个自定义的类对象时,可以返回一个其构造函数。用构造函数来生成一个新对象,可以避免麻烦。

13. 友元函数如果是在类声明中进行定义,尽管没有inline关键字,但将是一个内联友元函数。

14. 随机数

头文件cstdlib(stdlib.h)包含了srand()和rand()的原型,而ctime(time.h)包含了time()的原型。C++使用头文件random中的函数提供了更强大的随机数支持。

15. 在C++中,接受一个参数的构造函数为将类型与该参数相同的值转换为类提供了蓝图,而且支持隐式转换。

Stonewt(double lbs);

Stonewt myCat;

myCat = 19.6;

只有接受一个参数的构造函数才能作为转换函数。下面的构造函数有两个参数,因此不能用来转换。

Stonewt(int stn, double lbs);

然而,如果第二个参数提供默认值,它便可以用来转换int:

Stonewt(int stn, double lbs = 10);

16. 编译器在什么时候使用Stonewt(double)函数进行隐式类型转换呢?

1)  将Stonewt对象初始化为double值时。

2)  将double值赋值给Stonewt对象时。

3)  将double值传递给接受Stonewt参数的函数时。

4)  返回值被声明为Stonewt的函数试图返回double值时。

5)  在上述任意一种情况,使用可转换为double类型的内置类型时

Stonewt Jumbo(7000);

Jumboo = 7300;

17. 隐式类型转换有时会带来意外的灾难,C++新增了关键字explicit用来关闭这种特性。

explicit Stonewt(double lbs);

这将关闭上述示例中的隐式转换,当仍然允许显示转换。

Stonewt myCat;

myCat = 19.6; //not valid

myCat = Stonewt(19.6);// ok

myCat = (Stonewt)19.6;// ok

18. 转换函数

构造函数只用于从某种类型到类类型的转换。要进行相反的转换,必须使用转换函数。P415

定义转换函数后,既可以使用强制转换,也可以让编译器自动进行隐式转换。

Stone wolfe(285.7);

double host = double(wolfe);

double thinker = (double)wolfe;

double star = wolfe;

要转换为typeName类型,需要使用这种形式的转换函数:

  • operator typeName();

请注意以下几点:

1)  转换函数必须是类方法;

2)  转换函数不能指定返回类型(typeName已经给出了);

3)  转换函数不能有参数(已经隐式提供了);

例如,转换为double类型的原型如下:operator double();

19. 应该谨慎地使用隐式转换函数。原则上说,最好使用显式转换函数,避免隐式转换函数。在C++98中,关键字explicit不能用于转换函数,但C++11消除了这种限制。因此,在C++11中,可将转换运算符声明为显式的。

例如:

explicit operator int() const;

C++ primer plus读书笔记——第11章 使用类的更多相关文章

  1. C++ primer plus读书笔记——第16章 string类和标准模板库

    第16章 string类和标准模板库 1. string容易被忽略的构造函数: string(size_type n, char c)长度为n,每个字母都为c string(const string ...

  2. C++ primer plus读书笔记——第14章 C++中的代码重用

    第14章 C++中的代码重用 1. 使用公有继承时,类可以继承接口,可能还有实现(基类的纯虚函数提供接口,但不提供实现).获得接口是is-a关系的组成部分.而使用组合,类可以获得实现,但不能获得接口. ...

  3. C++ primer plus读书笔记——第10章 对象和类

    第10章 对象和类 1. 基本类型完成了三项工作: 决定数据对象需要的内存数量: 决定如何解释内存中的位: 决定可使用数据对象执行的操作或方法. 2. 不必在类声明中使用关键字private,因为这是 ...

  4. C++ primer plus读书笔记——第17章 输入、输出和文件

    第17章 输入.输出和文件 1. 对键盘进行输入缓冲可以让用户在将输入传输给程序之前返回并更正.C++程序通常在用户按下回车键时刷新输入缓冲区. 2. 一些I/O类 streambuf类为缓冲区提供了 ...

  5. C++ primer plus读书笔记——第15章 友元、异常和其他

    第15章 友元.异常和其他 1. 友元类的所有方法都可以访问原有类的私有成员和保护成员.另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元.哪些函数.成员函数.或类为友元是由类定义的, ...

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

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

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

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

  8. C++ primer plus读书笔记——第9章 内存模型和名称空间

    第9章 内存模型和名称空间 1. 头文件常包含的内容: 函数原型. 使用#define或const定义的符号常量. 结构声明. 类声明. 模板声明. 内联函数. 2. 如果文件名被包含在尖括号中,则C ...

  9. C++ primer plus读书笔记——第8章 函数探幽

    第8章 函数探幽 1. 对于内联函数,编译器将使用相应的函数代码替换函数调用,程序无需跳到一个位置执行代码,再调回来.因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存. 2. 要使用内 ...

随机推荐

  1. VS2008开发WinCE程序编译速度慢的解决办法

    1.找到以下文件 C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets 2.用记事本打开该 ...

  2. Fishing Master HDU - 6709

    题目链接:https://vjudge.net/problem/HDU-6709 题意:给出n条鱼的抓捕时间k和煮鱼时间a[i],你要在最短时间把所有鱼都煮了.(注意你只有一口锅) 思路:首先我们必须 ...

  3. CodeForces - 1360C

    C. Similar Pairs time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  4. P1423_小玉在游泳(JAVA语言)

    题目描述 小玉开心的在游泳,可是她很快难过的发现,自己的力气不够,游泳好累哦. 已知小玉第一步能游2米,可是随着越来越累,力气越来越小, 她接下来的每一步都只能游出上一步距离的98%. 现在小玉想知道 ...

  5. matplotlib常规使用方法

    1,指定图片大小和像素 Python绘图问题:Matplotlib中指定图片大小和像素 2,绘图命令的基本架构及其属性设置 绘图与可视化 3,python基础语法(二)--- plt的一些函数使用 p ...

  6. 力扣 - 92. 反转链表II

    目录 题目 思路1(迭代) 代码 复杂度分析 思路2(递归) 代码 复杂度分析 题目 92. 反转链表 II 思路1(迭代) 将反转链表分成3个部分:前一段未反转的部分.待反转链表部分.后一段未反转部 ...

  7. 什么是事务?事务的四个特性(ACID)?并发事务带来哪些问题?事务隔离级别都有哪些?事务的传播特性

    什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事物的四个 ...

  8. Vue组件(35)动态组件 component 的 is 到底可以是啥?

    component 动态组件 Vue官网上提供了一个动态组件 <component :is="currentTabComponent"> ,那么这里的 is 到底是什么 ...

  9. 火爆外网的 DGS 框架使用

    Netflix 已开放其 Domain Graph Service(DGS)框架的源代码 ,该框架是为了方便整合 GraphQL 使用,用于简化 GraphQL 的实现. GraphQL 主要是作用于 ...

  10. 「Spring Boot 2.4 新特性」一键构建Docker镜像

    背景 在我们开发过程中为了支持 Docker 容器化,一般使用 Maven 编译打包然后生成镜像,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很方便.docker-maven-plugi ...