最好不要把对象的定义和类的定义放在一起,这么做无异于把两种不同实体的定义混在了一条语句里,一会定义类,一会又定义变量,显然这是一种不被建议的行为。

类的定义最后要加上分号(:)

成员函数的声明必须放在类的内部,它的定义则既可以在类的内部也可以在类的外部,而作为接口组成部分的非成员函数,例如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 笔记的更多相关文章

  1. C#图解教程 第七章 类和继承

    类和继承 类继承访问继承的成员所有类都派生自object类屏蔽基类的成员基类访问使用基类的引用 虚方法和覆写方法覆写标记为override的方法覆盖其他成员类型 构造函数的执行 构造函数初始化语句类访 ...

  2. 《Java并发编程实战》第七章 取消与关闭 读书笔记

        Java没有提供不论什么机制来安全地(抢占式方法)终止线程,尽管Thread.stop和suspend等方法提供了这种机制,可是因为存在着一些严重的缺陷,因此应该避免使用. 但它提供了中断In ...

  3. 【C++】《C++ Primer 》第七章

    第七章 类 一.定义抽象数据类型 类背后的基本思想:数据抽象(data abstraction)和封装(encapsulation). 数据抽象是一种依赖于接口(interface)和实现(imple ...

  4. ArcGIS API for JavaScript 4.2学习笔记[24] 【IdentifyTask类】的使用(结合IdentifyParameters类)(第七章完结)

    好吧,我都要吐了. 接连三个例子都是类似的套路,使用某个查询参数类的实例,结合对应的Task类,对返回值进行取值.显示. 这个例子是Identify识别,使用了TileLayer这种图层,数据来自Se ...

  5. Android群英传笔记——第七章:Android动画机制和使用技巧

    Android群英传笔记--第七章:Android动画机制和使用技巧 想来,最 近忙的不可开交,都把看书给冷落了,还有好几本没有看完呢,速度得加快了 今天看了第七章,Android动画效果一直是人家中 ...

  6. 学习笔记(二)--->《Java 8编程官方参考教程(第9版).pdf》:第七章到九章学习笔记

    注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法者自负一切 ...

  7. [学习笔记—Objective-C]《Objective-C-基础教程 第2版》第二章~第七章

    在看完<Objective-C 程序设计 第6版>之后,看了一些关于iOS开发职位的面试题,发现自身基础非常是不牢,于是打算以查缺补漏的方式阅读还有一本关于Objective-C的基础书籍 ...

  8. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二) 代码工程地址: https:/ ...

  9. JVM学习笔记-第六章-类文件结构

    JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...

随机推荐

  1. ROS开发--在订阅话题的回调函数中发布话题

    处理激光数据时,需要将处理后的激光数据再发布,需要保持一致的频率,所以必须在回调函数中发布激光数据信息. 代码参考:https://blog.csdn.net/heyijia0327/article/ ...

  2. exe 发布为服务

    参考连接: https://www.cnblogs.com/liuxiaoji/p/8016261.html 1.有两个文件 srvany.exe,instsrv.exe 然后放到指定的文件下下: 2 ...

  3. 0219 springmvc-拦截器和响应增强

    拦截器 拦截器分同步拦截器和异步拦截器: HandlerInterceptor 方法和执行时机 可以看DispathcerServlet的原来确定它的三个方法的执行时机: AsynHandlerInt ...

  4. java开发就业招聘管理系统 ssh源码

    开发环境:    Windows操作系统开发工具: MyEclipse+Jdk+Tomcat+MySql数据库 此项目分为 用户 企业  管理员三种角色 运行效果图

  5. Hadoop报错:org.apache.hadoop.security.AccessControlException: Permission denied: user=xxxx

    问题出现原因: 因为远程提交hadoop的任务的情况下如果,没有hadoop 的系统环境变量,就会读取当前主机的用户名,所以Hadoop集群的节点中没有该用户名的权限,所以出现的异常. 解决方法: S ...

  6. 获取url参数(jq 扩展包)

    (function($){ $.extend({ urlGet:function(url) { var getUrl = url ? url.split("?") : window ...

  7. ASP.NET MVC5 的请求管道和运行生命周期

    https://www.jianshu.com/p/848fda7f79e0 请求处理管道 请求管道是一些用于处理HTTP请求的模块组合,在ASP.NET中,请求管道有两个核心组件:IHttpModu ...

  8. 图灵,咕泡,鲁班学院--Java高级架构师-互联网企业级实战VIP课程(价值6380)

    课程介绍:        讲课内容涉及Java互联网技术工程框架.应用框架.        性能调优 (Tomcat Nginx JVM)         分布式框架(并发编程 Zookeeper N ...

  9. pytest-pytest-html生成HTML测试报告

    pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告.兼容Python 2.7,3.6 pytest-html 1.github上源码地址[https://github.com ...

  10. Python中pip的使用

    1.pip安装模块 pip install 模块名称 -i 安装源 pip install requests -i https://mirrors.aliyun.com/pypi/simple/