C++语言中的类型(二)
——分门别类是简化事物最有效的方式。
C++语言的强大能力的体现在对程序员自定义数据类型的支持。C++语言主要的一个设计目标就是让程序员自定义的数据类型像内置类型一样好用。
一、自定义数据类型
数据类型告诉我们数据的意义以及我们能在数据上执行的操作。因而自定义数据类型把数据及其对应操作组合在一起。
类的定义形式:
class ClassName
{
//数据
…
//操作
…
};
二、类的实例化方式
如何实例化一个类呢?最简单直接的方式就是模具铸造技术。就是把类的定义作为一个模具,铸造出一个个对象。这种方式最直接,也最容易理解,但效率却不高。那么应该如何实例化呢?其实也很简单,同中国的活字印刷术一样,只需要稍微转变一下观念。何必非要坚持对象的内容在物理上的连续性呢,只要对象的内容是完整的,就足够了。因而我们的眼中不再是一页一页的文字(类),而是一个个字(类成员)。
1、按照这种思路,可以把类成员抽象为两种类型
1) 同一类型的所有实例都相同的类成员
这种类成员,一个程序中保存一份就足够了。
2) 同一类型的各个实例不相同的类成员
这种类成员,每个对象都需要一份,以便呈现自己的独特风采。
2、数据成员与成员函数的实例化
(1)数据成员
按照上述对类成员的抽象,数据成员被区分为两类:
1) 属于类的数据成员(static)
一个程序保留一份即可,由类进行初始化。
2) 属于对象的数据成员(默认状态)
每个对象包含一份,由每个对象进行初始化。
(2)成员函数(方法)
其实对于同一类型的所有实例,它们所具有的方法是相同的,即方法只属于类,而不独属于某个对象,因而一个程序中具有一份就足够了。然而由于数据成员具有两种类型,因而C++根据方法对数据成员的操作方式的不同,分为两种类型:
1) 不可以直接(其实并不是真正的直接,下面会谈到)操作属于对象的数据成员(static)
2) 可以直接操作属于对象的数据成员(默认状态)
试图把数据成员和成员函数的分类统一起来,其实反而会带来更多的困扰,因为它们的分类依据本来就不相同。成员函数的分类依据其实很简单,就是this参数(隐式参数)的声明形式不同而已。
1) 常量成员函数(const)
const ClassName *const this;//指向常量对象的常量指针
因而常量函数不能改变对象的数据成员,常量对象不能调用非常量函数(this形参无法初始化)。
2) 静态成员函数(static)
没有声明this参数,因而不可以通过this指针操作对象的成员。
3) 普通成员函数(默认状态)
ClassName *const this;//指向普通对象的常量指针
从这里我们可以看出,本质上,成员函数和其他的函数并没有什么不同(仅仅书写形式上不同而已),都需要借助参数来访问函数之外的对象。
三、读写属性的控制
仅仅把数据和操作简单地组合在一起,还不能称之为是一个真正的类,只能称之为一个代码的集合而已。还需要添加对成员的读写权限。对于自定义类型,C++语言把类的成员的读写属性抽象为两个级别。
1、 特殊读写属性(可见性)的控制
成员的可见性(可见性是对于类外而言)是读写属性中比较特殊的一种,它区分了类内和类外,达到了对数据的封装。成员的可见性具有两个状态(暂不考虑继承,其实有了继承也不过是再增加一个protected而已。):
1) 可见(public)
2) 不可见(private)
为了代码的清晰,C++语言不再依赖默认状态,允许以更明确的方式控制成员的可见性。
2、 普通读写属性的控制
普通级别的读写属性控制和普通变量一样,是专门针对数据成员的。由类的实例化方式可知,无论是类外还是类的成员函数,其实都是通过对象以间接的方式访问其数据成员。因而都是典型的二层结构。
如图A是一个类对象,A包含3个public权限的数据成员:a、b和c。
对于对象A,它和普通变量一样,用const声明其为常量对象,用默认状态声明其为非常量对象。当A为一个常量对象时,相当于在对象的最外层镶了一层特殊的铁皮,只能通过A对A中的数据成员进行读操作,而不能进行写操作。如果变量a、b和c都是默认读写状态,声明A为常量对象就相当于(实际上并不等同,因为常量属性只施加在了外层对象上,只要突破了这层保护,该声明也就没有意义了。)变量a、b和c都是常量了。这样很不灵活,无法对数据成员的读写属性进行精细化控制,因而C++允许类的数据成员具有三种读写状态:
1) 总是仅可读(const)
2) 总是可读写(mutable)
3) 与类对象的声明一致(默认状态)
这样,我们就可以对任一个数据成员施加我们期望的读写权限了。
四、类型间沟通的门户
我们把事物分割在一个个相互隔离的框架内,既是为了简化问题,也是为了安全。但不同事物间是需要沟通的,因而C++语言在设置了一个个条条框框之后也开辟了几个门户,以达到沟通的目的,同时又可以设置重兵监督把守。
C++语言中的门户主要有以下几种:
1) 类型转换
通过定义转换构造函数,可以实现不同类型间的转换。但需要注意的是,与内置数据类型不同,一般的类型之间并没有那么强的联系,因而类型转换往往是没有必要的,而且会带来很大的安全风险。因此,通常情况下,应该抑制类型间的转换,把转换构造函数声明为explicit。
2) 成员函数
上面说到了,类型转换是危险的,而且往往是没有必要的。当两个类型间只有一种操作有联系时,定义一个函数应该是最合适的。
3) 友元
类的公共接口的设计应当是满足用户最常见的一般性需求。但是有一般的用户,肯定就有一些需求刁钻的用户。为了满足所有用户的需求,而把类设计得异常庞大是没有必要的。于是C++提供了友元,授予友元对类的所有成员的访问权限。通过友元,你可以如设计成员函数一样,设计出满足自己需求的高效接口,同时又不改变类的一般结构。可以说,友元提出的初衷是非常好的,但是这种不负责任的态度却也是危险的——你给别人开了后门,然后就理所当然地撒手不管了,那么有心人就可能背地里干些坏事了。
C++语言中的类型(二)的更多相关文章
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- C语言中不同类型的循环(Different types of loops in C)
C语言中有三种类型的循环:for,while,do-while. while循环先判断循环条件. while (condition) { //gets executed after condition ...
- C++语言中的类型(一)
--分门别类是简化事物最有效的方式. 类型是C++语言的基础,对象类型决定了能对该对象进行的操作. 一.基本内置数据类型 C++预先定义的基本内置数据类型是构造世界万物的原子,数据类型告诉我们数据的意 ...
- C语言中的指针(二)
指针指向谁,就把谁的地址赋给指针,指针变量和指针指向的内存变量是不一样的.不停的给指针赋值,相当于是不断的改变指针的指向. 在开发中要避免野指针的存在,在指针使用完毕之后,记得要给指针赋值成为NULL ...
- C#语言中的类型转换方法(unfinished)
一.C#中的数据类型 1.数值类型 2.字符类型 3.字符串类型 4.布尔类型 5.枚举类型 6.Object类型 二.常见的类型转换 从转换方式的角度,类型转换分为隐式转换与显式转换两种. 其中,隐 ...
- php弱类型语言中的类型判断
1.php一个数字和一个字符串进行比较或者进行运算时,PHP会把字符串转换成数字再进行比较.PHP转换的规则的是:若字符串以数字开头,则取开头数字作为转换结果,若无则输出0. 例如:123abc转换后 ...
- C语言中不同类型的数据转换规则
不同类型数据间的混合运算与类型转换 1.自动类型转换 在C语言中,自动类型转换遵循以下规则: ①若参与运算量的类型不同,则先转换成同一类型,然后进行运算 ②转换按数据长度增加的方向进行,以保证精度不降 ...
- 关于C语言中不同类型数据进行计算 有符号和无符号数进行计算
float是8个有效位, 做个试验: 输出如下: 上面说明了什么: 1, 18/2.2 是除不尽的, 因为是define,所以没有给ratio变量赋值类型,但是从sizeof输出的结果是8,所以系统默 ...
随机推荐
- Xadmin集成富文本编辑器ueditor
在xadmin中通过自定义插件,实现富文本编辑器,效果如下: 1.首先,pip安装ueditor的Django版本: pip install DjangoUeditor 2.之后需要添加到项目的set ...
- ABAP 在屏幕上显示图片
1.se78 上传 或 预览图片 图片预览 2.程序代码 定义各变量 DATA: H_PICTURE TYPE REF TO CL_GUI_PICTURE, H_PIC_CONTAINER TYPE ...
- db2备份还原
还原步骤:创建好数据库后进入该数据库 .restore db TSMESDB from D:\ICSS\dbData on D:\ICSS\dbData into TSMESDB redirect. ...
- property--staticmethod--classmethod
特性(property): 作为装饰器使用,调用方式从最初的方法调用改变为属性调用 类方法(classmethod):和类进行交互,单不和实例进行交互 在函数中可以不用上传参数 静态方法(static ...
- 【转】C缺陷和陷阱学习笔记
http://www.cnblogs.com/hbiner/p/3591335.html?utm_source=tuicool&utm_medium=referral 这段时间把<C陷阱 ...
- oracle建表权限问题和JSP连接oracle数据库基本操作
JSP连接oracle数据库相关操作 1.创建表 打开Enterprise Manager Console,为用户添加权限CREATE ANY TABLE和分配一定的表空间USERS限额1024k. ...
- [mysql使用(1)] 64位Linux下安装mysql-5.7.13-linux-glibc2.5-x86_64
由于公司临时让将Oracle的数据移植到mysql上面,所以让我在公司服务器上面安装一下mysql.下面就是我的安装过程以及一些错误解决思路.其实对于不同版本安装大体都有差不多. 1. 从官网下载 m ...
- webpack核心概念
一.webpack四个核心概念 1.入口[Entry] webpack将创建所有应用程序 依赖关系图表.图表的起点被称之为 入口起点.入口起点告诉webpack从哪里开始,并遵循着依赖关系图表知道打包 ...
- CSDN文章抓取
在抓取网页的时候只想抓取主要的文本框,例如 csdn 中的主要文本框为下图红色框: 抓取的思想是,利用 bs4 查找所有的 div,用正则筛选出每个 div 里面的中文,找到中文字数最多的 div 就 ...
- pandas.DataFrame学习系列1——定义及属性
定义: DataFrame是二维的.大小可变的.成分混合的.具有标签化坐标轴(行和列)的表数据结构.基于行和列标签进行计算.可以被看作是为序列对象(Series)提供的类似字典的一个容器,是panda ...