第七章 类(class)7.1 笔记
最好不要把对象的定义和类的定义放在一起,这么做无异于把两种不同实体的定义混在了一条语句里,一会定义类,一会又定义变量,显然这是一种不被建议的行为。
类的定义最后要加上分号(:)
成员函数的声明必须放在类的内部,它的定义则既可以在类的内部也可以在类的外部,而作为接口组成部分的非成员函数,例如add、 read、和print等,他们的定义和声明都在外部
任何对类成员的直接访问都被看做this的隐式引用,也就是说,当isbn使用bookNo时,它隐式地使用this指向的成员,就像我们书写了this -> bookNo一样。this不能用作任何形参名和变量名。
std::string isbn() const { return this -> bookNo ;}
//因为this的目的总是指向这个对象,所以this是一个常量指针。紧跟在参数列表后面的const 表示this是一个指向常量的指针。像这样使用const的成员函数被称作常量成员函数(指明这个函数不会修改这个类的任何数据成员的值)。
可以把isbn()函数想象成如下形式
//伪代码,不能显示的定义this指针
std::string Sales_data::isbn(const Sales_data *const this) const { return this -> bookNo ;}
常量对象和常量对象的引用或指针都只能调用常量成员函数
编译器分两步处理类:首先编译成员的声明,然后才轮到成员函数体(如果有的话)。因此,成员函数体可以随意使用类中的其他成员而无需在意这些成员出现的次序。
像其它函数一样,当我们在类外部定义成员函数时,成员函数的定义必须与它的声明匹配。也就是说返回类型、参数列表和函数名都得与类内部的声明保持一致。如果成员被声明称常量成员函数,那么他的定义也必须在参数列表后表明指定const属性。同样,类外部定义的成员的名字必须包含它所属的类名:
double Sales_data::avg_price() const { //Sales_data::加在函数名之前而非返回类型之前
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this; //返回调用该函数的对象
}
当我的交易处理程序调用如下的函数时,
total.combine(trans);
total的地址被绑定到隐式地this参数上,而rh绑定到了trans上。
这个函数一个值得关注的部分是它的返回类型和返回语句。一般来说,当我们定义的函数类似于某个内置运算符时,应该令该函数的行为尽量模仿这个运算符。内置的赋值运算符把他的左侧运算对象当成左值返回,因此为了与他保持一致性,combine函数必须返回引用类型。所以返回类型为Sales_data&。
int &refVal = ival; //refVal 是ival的引用,是ival的另一个名字
既然Sales_data的数据成员是private的,我们的read、print、和add函数也就无法正常编译了,这是因为尽管这几个函数是类的接口的一部分,但他们不是类的成员,类可以允许其他类或者函数访问它的非公有成员,方法是令其它类或函数成为它的友元(friend),只需要增加一条以friend关键字开始的函数声明语句即可
istream &read(istream &is, Person &item)//编译无法通过,要在类内部添加函数友元声明
{
is >> item.strName >> item.strAddress;
return is;
}
friend istream &read(istream &, Person &);//友元声明
7.14构造函数
构造函数的名字和类名相同。和其他函数不一样的是,构造函数没有返回类型;构造函数也有一个(可能为空的)参数列表和一个(可能为空的)函数体。类可以包含多个构造函数,和其他重载函数差不多, 不同的构造函数之间必须在参数数量或参数类型上有所区别。此外,构造函数不能被声明成const的。
默认构造函数又称之为合成的默认构造函数。
某些类不能依赖于合成的默认构造函数的情况:
1.只有当类没有声明任何构造函数时, 编译器才会自动地生成默认构造函数
2.如果类包含有内置类型或者复合类型的成员,则只有当这些成员全都被赋予了类内的初始值时,这个类才适用于合成的默认构造函数。(复合类型就是使用其他类型定义的类型,有三种复合类型,引用、指针、数组),内置类型就是(int、char、double、unsigned 等基本类型,若没有给这些成员初始值,默认值可能是未定义的)
3.如果类中包含一个其他类类型的成员且这个成员的类型没有默认构造函数,那么编译器就无法初始化该成员,也就无法生成默认的构造函数。对于这样的类来说,必须自定义默认构造函数。(classname() = default)
=default(默认构造函数)
构造函数初始值列表
Sales_data(const std::string &s) : bookNo(s) { }//未显示初始化的部分按默认初始化的方式初始化
等价于:
Sales_data(const std::string &s) : bookNo(s), units_sold(0), revenue(0) { }
Sales_data(const std::string &s, unsigned n, double p) : //初始值列表
bookNo(s), units_sold(n), revenue(p * n) { }
等价于
Sales_data(const std::string &s, unsigned n, double p)
{
bookNo = s;
units_sold = n;
revenue = p * n;
}
二者有一些小小的区别,那就是前者是通过初始化的方式,后者是通过赋值的方式
构造函数最好使用类内初始值或初始值列表
重载运算符:
friend ostream &operator << (ostream & os, const Sales_data & rhs);
friend istream& operator >> (istream &is, Sales_data & rhs);
第七章 类(class)7.1 笔记的更多相关文章
- C#图解教程 第七章 类和继承
类和继承 类继承访问继承的成员所有类都派生自object类屏蔽基类的成员基类访问使用基类的引用 虚方法和覆写方法覆写标记为override的方法覆盖其他成员类型 构造函数的执行 构造函数初始化语句类访 ...
- 《Java并发编程实战》第七章 取消与关闭 读书笔记
Java没有提供不论什么机制来安全地(抢占式方法)终止线程,尽管Thread.stop和suspend等方法提供了这种机制,可是因为存在着一些严重的缺陷,因此应该避免使用. 但它提供了中断In ...
- 【C++】《C++ Primer 》第七章
第七章 类 一.定义抽象数据类型 类背后的基本思想:数据抽象(data abstraction)和封装(encapsulation). 数据抽象是一种依赖于接口(interface)和实现(imple ...
- ArcGIS API for JavaScript 4.2学习笔记[24] 【IdentifyTask类】的使用(结合IdentifyParameters类)(第七章完结)
好吧,我都要吐了. 接连三个例子都是类似的套路,使用某个查询参数类的实例,结合对应的Task类,对返回值进行取值.显示. 这个例子是Identify识别,使用了TileLayer这种图层,数据来自Se ...
- Android群英传笔记——第七章:Android动画机制和使用技巧
Android群英传笔记--第七章:Android动画机制和使用技巧 想来,最 近忙的不可开交,都把看书给冷落了,还有好几本没有看完呢,速度得加快了 今天看了第七章,Android动画效果一直是人家中 ...
- 学习笔记(二)--->《Java 8编程官方参考教程(第9版).pdf》:第七章到九章学习笔记
注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法者自负一切 ...
- [学习笔记—Objective-C]《Objective-C-基础教程 第2版》第二章~第七章
在看完<Objective-C 程序设计 第6版>之后,看了一些关于iOS开发职位的面试题,发现自身基础非常是不牢,于是打算以查缺补漏的方式阅读还有一本关于Objective-C的基础书籍 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二) 代码工程地址: https:/ ...
- JVM学习笔记-第六章-类文件结构
JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...
随机推荐
- gulp常用插件之cssnano使用
更多gulp常用插件使用请访问:gulp常用插件汇总 cssnano这是一款将你的 CSS 文件做 多方面的的优化,以确保最终生成的文件 对生产环境来说体积是最小的插件. 更多使用文档请点击访问cha ...
- Constructing Roads POJ - 2421 最小生成树板子题
#include<iostream> #include<cstring> #include<algorithm> using namespace std; ; in ...
- 树莓派3b 换国内源 更新源
在国内要更新源的时候,因为是国外的源,总会出现网速太慢的问题, 以下是对于安装了,2017-11-29-raspbian-stretch 系统源 更换最好用root登陆操作 sudo passwd r ...
- 树莓派使用Python使用PiCamera录制视频
个人博客 地址:https://www.wenhaofan.com/article/20190430144020 代码 在树莓派环境下官方提供了乐酷 PiCamera 让我们可以很方便的操作树莓派连接 ...
- JXLS支持嵌套循环语法的数据导出说明
今天在试验用Jxls 2.0导出嵌套循环数据时,第二层数据一直没有成功,最后确认是数据源结构不正确所致,现将这两种数据格式进行说明:假设模板中批注有这样两条循环语法: <jx:each(item ...
- 51Nod 1068 Bash游戏 V3 (这规律不好找)
有一堆石子共有N个.A B两个人轮流拿,A先拿.每次拿的数量只能是2的正整数次幂,比如(1,2,4,8,16....),拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出 ...
- pandas 读取excel时,遇到数字变为科学计数法了, 怎么破?? 别慌 这样来处理
# 指定字段以string 方式读取 df = pd.read_excel("./test.xlsx", converters={"id": str})
- [TJOI2013] 奖学金 - 堆
按 a 排序,暴力用堆维护两侧预处理, 然后枚举中位数即可 #include <bits/stdc++.h> using namespace std; #define int long l ...
- AntDesign(React)学习-3 React基础
前面项目已经建起来了,但是没有React基础怎么办,从头学习,这个项目使用的是基于React16.X版本的几种技术集成,那么我们就从网上找一些相关的资料进行研究,我的习惯是用到哪学到哪. 一.先看一些 ...
- 使用ScrollRect制作翻页
1.标准的层级结构 ScrollRect->ViewPort->Content,Viewport负责显示区域的大小一般和Mask一起配合使用,Content使用Layout来布局,如果想使 ...