C++语言提供了一些内置的类型,如char、int和double。对于一个类型,如果编译器无须借助程序员在源码中提供的任何声明,就知道如何表示这种类型的对象以及可以对它进行什么样的运算,我们就称这种类型是内置的。

非内置的类型称为用户自定义类型(user-defined type , UDT)。用户自定义的类型包括每个ISO标准C++实现都提供给程序员的标准库类型,如string,vector和ostream。

我们为什么要创建自定义类型呢?原因在于编译器不知道我们想在程序中使用的所有类型。它也不可能知道,因为有用的类型实在太多了--没有语言设计者或者编译器开发者能预知所有类型。通过类型,我们可以在代码中直接、有效地表达我们的思想。

C++提供了两类用户自定义数据类型:类和枚举。类是到目前为止最常用,也是最重要的概念描述机制,因此我们首先把注意力放在类上。类能够在程序中直接地表达概念。一个类是一个(用户自定义)类型是,它指出这种类型的对象如何表示,如何创建,如何使用,以及如何销毁。在C++中(以及大多数现代程序设计语言中),类是构造大型程序的关键的基本组成部分,对小程序也同样的非常有用。

一个类就是一个用户自定义类型,由一些内置类型和其他用户自定义类型的对象以及一些函数组成

。这些用来定义类的组成部分称为成员(member)。一个类可以有0个或多个成员,例如:

class X
{
public:int m; //data memberint mf(int v) {int old = m; m = v; return old;}  //成员函数
}

成员可以有许多种类别,大多数要么是数据成员,定义了类对象的表示方法,要么是函数成员,提供类对象之上的运算。类成员的访问使用这种符号:对象.成员。

我们通常把一个类看做一个接口加上一个实现。接口是类声明的一部分,用户可以直接访问它。实现是类声明的另一部分,用户只能通过接口间接访问它。公共的接口用标号public:标识,实现用private:标识。你可以将一个类声明理解为如下形式:

class X
{public:private:
}

类成员默认是私有的,也就是说,如下代码所示:

class X
{int mf(int);//...
};

等价于

class X
{private:int mf(int);// ...
};

因此,下面的代码是错误的:

X x;
int y = x.mf();

用户不能直接访问一个私有成员,应通过一个公有函数来访问,例如:

class X
{int m;int mf(int);public:int f(int i) { m = i; return mf(i);}
};
X x;
int y = x.f(2);

我们用私有和公用之间的差别来描述接口(类的用户视图)和实现细节(类的实现者视图)之间的重要区别

。C++提供了一种很有用的简化的功能,可用来描述没有私有实现细节的类。这种语法功能就是结构,一

个结构就是一个成员默认为公用属性的类:

struct X
{int m;// ...
};

意味着

class X
{public:int m;// ...
};

结构主要用于成员可以取任意值的数据结构,即我们不能定义结构有意义的不变式。

与类同名的成员函数是特殊的成员函数,称为构造函数(constructor),专门用于类对象的初始化("构造

")。如果一个类具有需要参数的构造函数,而程序员忘记利用它初始化类对象,则编译器会捕获这个错

误。C++提供了一种专用的,而且很方便的语法来进行这种初始化,例如:

struct Date {int y,m,d; Date(int y, int m, int d); void add_day(int n);};
Date my_birthday;  //错误,没有初始化成员。
Date today(12,24,2007); //错误,运行时错误。
Date last(2000,12,31); //正确。

运算符重载

你可以在类或枚举对象上定义几乎没有C++运算符,这通常称为运算符重载(operator overloading)。这

种机制用于为用户自定义类型提供习惯的符号表示方法。

enum Month {Jan = 1,Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
Month operator++(Month& m)
{m = (m == Dec)?Jan:Month(m+1);return m;
}

其中?:是“算术if"运算符:当(m == Dec)时m的值变为Jan,否则m的值为Month(m+1)。这是十二月后"绕回"一月这一事实的一种非常简洁的描述方法。我们可以像如下代码一样使用Month类型。

Month m = Sep;
++m;  //m变为Oct
++m;  //m变为Nov
++m;  //m变为Dec
++m;  //m变为Jan

你可能觉得增加Month对象值这样的操作没那么常用,不至于设计一个专门的运算符。可能确实是这样,

那么输出运算符又如何呢?如下代码定义了一个输出运算符:

vector<string> month_tbl;
ostream& operator<<(ostream& os, Month m) { return os << month_tbl[m];}

  你可以为自己的类型重新定义几乎没有的C++运算符,如+、-、*、/、%、[]、()、^、!、&、<、<=

、>和>=等。但你不能定义新的运算符。

  一个重载的运算符必须作用于至少一个用户自定义类型的运算对象:

int operator+(int ,int); //错误,不能重载内置运算符+
vector operator+(const vector&, const vector &); //OK
vector operator+=(const vector&, int); //OK

一个一般性的原则是:除非你真正确定重载运算符能大大改善代码,否则不要为你的类型定义运算符。而且,重载运算符应该保持其原有意义:+就应该是加法,二元运算符*就应该表示乘法,[]表示元素访问,()表示调用,等等。这只是建议,并不是C++语言规则,但这是一个有益的建议:按习惯使用运算符,例如+只用做加法,对我们理解程序会有极大的帮助。毕竟,这种习惯用法源于人们千百年使用数学符号的经验。相反,含混不清的运算符和常规不符的使用方式是混乱和错误之源。

类接口

类的公有接口和实现部分应该分离。但是,如何来设计一个好的接口呢?

(1)保持接口的完整性。

(2)保持接口的最小化。

(3)提供构造函数。

(4)支持(或禁止) 拷贝。

(5)使用类型来提供完善的类型检查。

(6)支持不可修改的成员函数。

(7)在析构函数中释放所有的资源。

前两条原则可以归结为"保持接口尽可能小,但不要更小了“。我们希望接口尽量小,是因为小的接口易于学习和记,而实现者也不会为不必要的和很少使用的功能浪费大量时间。小的接口还意味着当错误发生时,我们中需要检查很少的函数来定位错误。平均来看,公有成员函数越多,查找bug就越困难--调试带公有数据的类是非常复杂的,不要让陷入其中。当然,前提还是要保持完整性,否则,接口就没有用处了。如果一个接口无法完成我们真正需要做的全部工作,我们是不会使用它的。

转载于:https://blog.51cto.com/hthinker/1588473

《C++程序设计原理与实践》读书笔记(二)相关推荐

  1. 深入理解JVM读书笔记二: 垃圾收集器与内存分配策略

    3.2对象已死吗? 3.2.1 引用计数法 给对象添加一个引用计数器,每当有一个地方引用它的地方,计数器值+1:当引用失效,计数器值就减1;任何时候计数器为0,对象就不可能再被引用了. 它很难解决对象 ...

  2. 《Docker 技术入门与实践》-读书笔记二

    <Docker 技术入门与实践>-读书笔记一 <Docker 技术入门与实践>-读书笔记二 一.数据管理 用户在使用 Docker 的过程中,往往需要能查看容器内应用产生的数据 ...

  3. 《Introduction To Modern Cryptography》读书笔记二

    <Introduction To Modern Cryptography>读书笔记二 本笔记纯粹个人读书习惯与相应见解,内容归纳完全出于个人需要与个人局限,如有修改意见(比如哪儿应该是值得 ...

  4. oracle直查和call哪个更快,让oracle跑的更快1读书笔记二

    当前位置:我的异常网» 数据库 » <>读书笔记二 <>读书笔记二 www.myexceptions.net  网友分享于:2013-08-23  浏览:9次 <> ...

  5. 《How Tomcat Works》读书笔记(二)

    <How Tomcat Works>读书笔记(二) 这是<How Tomcat Works>第一二章的读书笔记.第一张主要写了一个静态资源处理的web服务器,第二章加了对ser ...

  6. 3D游戏设计读书笔记二

    3D游戏设计读书笔记二 一.简答题 • 解释 游戏对象(GameObjects) 和 资源(Assets)的区别与联系.   GameObjects是一个具体的实例,Assets是包括诸多游戏素材的资 ...

  7. 《李元芳履职记》读书笔记二 IT技术管理的沟通与团队建设

    <李元芳履职记>读书笔记二 接一 https://blog.csdn.net/qq_45937199/article/details/103305223 IT技术人员从技术岗走向管理岗,所 ...

  8. python图像处理《数字图像处理与python实现》读书笔记二:空间滤波

    文章目录 重要! 第三章 空间滤波 概览 3.1 空间滤波基础 3.1.1 空间滤波的机理 3.1.2 空间滤波器模板 3.2 平滑处理 3.2.1 平滑线性空间滤波器 3.2.2 统计排序滤波器 3 ...

  9. 第一行代码 Android读书笔记(二)

    第一行代码 Android读书笔记 第三章 软件也要拼脸蛋-UI开发的点点滴滴 常用控件的使用方法 详解4种基本布局 自定义控件 最常用和最难用的控件-ListView 更加强大的滚动控件-Recyc ...

  10. 《淘宝技术这十年》读书笔记 (二).Java时代的脱胎换骨和坚若磐石

    马云说过"一个好的东西往往是是说不清楚的",姑且不论这句话的对与错.但我真的很佩服<淘宝技术这十年>这本书的作者子柳,能够通过淘宝的一些故事,按照时间顺序和IT发展的各 ...

最新文章

  1. 第十六届智能车竞赛线上比赛赛道审核 - 东北赛区第二批次
  2. 基于PyQt5的快速开发框架QFramer
  3. linux 进程简介
  4. 爬虫总结(三)-- cloud scrapy
  5. (二)性能优化的指标和工具 (告别前端小白,成为大神的必经之路)
  6. php imagecreatefromjpeg图片太大_PHP图像处理技术及应用
  7. sql语句优化之一:尽量使用索引避免全表扫描
  8. [数据库字典]简单的3个SQL视图搞定所有SqlServer数据库字典
  9. L2-002. 链表去重-PAT团体程序设计天梯赛GPLT
  10. 交通信息工程 实验三:交通信号机仿真实验
  11. Diy Win7 OEMlogo
  12. CentOS7 WordPress无法将上传的文件移动至wp-content/uploads/ ApacheNginx解决方案
  13. Java获取汉字的拼音
  14. 购买2019最佳性价比Android智能手表(smart watch)
  15. 补天漏洞平台为什么能吸引众多白帽和企业?
  16. sql语句-按照汉字拼音首字母排序
  17. 转载:网站分析与SEO效果的评估
  18. 浅谈 React Fiber
  19. 127.0.0.1:xxxx端口映射到物理机IP
  20. html引入axios文件,axios实现简单文件上传功能

热门文章

  1. 2021河南高考成绩查询郸城一高,郸城一高在河南有多牛 2021年高考成绩
  2. CodeForces 501B——Misha and Changing Handles
  3. C++关键字速查手册
  4. ubuntu下修复U盘只读问题
  5. 【汇编语言】(王爽)实验4解答
  6. Makefile规则介绍
  7. go build编译不同环境
  8. Django 【认证系统】auth
  9. 2018.09.16 loj#10243. 移棋子游戏(博弈论)
  10. HDUOJ 1062 TEXT REVERSE