C++ primer摘要(16)---特殊工具与技术

特殊工具与技术

控制内存分配

  • 当需要自定义内存分配细节时,需要使用new和delete运算符以控制内存分配的过程
重载new和delete
  • 尽管我们说能够重载new和delete,但实际上重载这两个运算符与重载其他运算符的过程大不相同
//new 表达式
string * sp = new string("a value");
string * arr = new string(10);
  • 上述new操作实际执行了散步
- [x] 1:new表达式调用一个名为operator new(或者operator new[])的标准库函数,该函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象
- [x] 2:编译器运行相应的构造函数以构造这些对象,并为其传入初始值

  • 运行时类型识别的功能由两个运算符实现
- [x] typeid运算符,用于返回表达式的类型
- [x] dynamic_cast运算符,用于将基类的指针或引用安全地转换成派生类地指针或引用
  • 当我们将这两个运算符用某种类型地指针或引用,并且该类型含有虚函数时,运算符将使用指针或引用所绑定对象地动态类型

枚举类型

  • 枚举类型使我们可以将一组整型常量组织在一起,和类一样,每个枚举类型定义了一种新的类型,枚举属于字面值常量类型
  • C++包含两种枚举:限定作用域地和不限定作用域地
- [x] C++11新标准引入了限定作用域地枚举类型,定义限定作用域地枚举类型一般形式是:首先是关键字enum class,随后是枚举类型名字以及用花括号括起来地以逗号分隔的枚举成员列表,最后是一个分号
enum class open_modes{input,output,append};
  • 定义不限定作用域的枚举类型时省略关键字class,枚举类型的名字是可选的:
enum color{red,yellow,green};
  • 默认情况下,枚举值从0开始,依次加1,不过也可以为一个或几个枚举成员指定专门的值
  • 枚举值不一定唯一,如果我们没有显示的提供初始值,则当前枚举成员的值等于之前枚举成员的值加1
  • 枚举成员是const,因此在初始化枚举成员时提供的初始值必须时常量表达式,也就是说,每个枚举成员本身就是一条常量表表达式,我们可以在任何需要常量表达式的地方使用枚举成员
  • 尽管每个enum都定义了唯一的类型,但实际上enum是由某种整数类型表示的,在C++11的新标准中,我们可以在enum的名字后面加上冒号以及我们想在该enum中使用的类型
enum intValues : unsigned long long {
    charTyp = 255,
    shortTyp = 65535
};
  • 如果我们没有指定enum的潜在类型,则默认情况下限定作用域的enum成员类型是int
  • 对于不限定作用域的枚举类型来说,其枚举成员不存在默认类型,我们只知道成员的潜在类型足够大,肯定能容纳枚举值
  • 指定enum潜在类型的能力使得我们可以控制不同实现环境中使用的类型,我们将可以确保在一种实现环境中编译通过的程序所生成的代码与其他实现环境中生成的代码一致

类成员指针

  • 成员指针是指可以指向类的非静态成员指针
  • 一般情况下,指针指向一个对象,但是成员指针指示的是类的成员,而非类的对象
  • 类的静态成员不属于任何对象,因此无须特殊的指向静态成员的指针,指向静态成员的指针与普通指针没有什么区别
  • 成员指针的类型囊括了类的类型以及成员的类型,当初始化一个这样的指针时,我们令其指向类的某个成员,但是不指定该成员所属的对象,直到使用成员指针时,才提供成员所属的对象

嵌套类

  • 一个类可以定义在另一个类的内部,前者称为嵌套类或嵌套类型
  • 嵌套类常用于定义作为实现部分的类
  • 嵌套类是一个独立的类,与外层类基本上没什么关系,特别是,外层类的对象和嵌套类的对象是相互独立的,在嵌套类的对象中不包含任何外层类定义的成员,类似的,在外层类的对象中也不包含任何嵌套类定义的成员

union:一种节省空间的类

  • union是一种特殊的类,一个union可以有多个数据成员,但是在任意时刻只有一个数据成员可以有值
  • 当我们给union的某个成员赋值之后,该union的其他成员就变成未定义的状态了
  • 分配给一个union对象的存储空间至少要能容纳它的最大的数据成员,和其他类一样,union顶i有了一种新类型
  • union不能含有引用类型的成员,除此之外,它的成员可以是绝大多数类型
  • 在C++11中,含有构造函数或析构函数䣌类类型也可以作为union的成员类型
  • union可以为其成员指定public、protected、private等保护标记
  • 默认情况下,union的成员都是公有的,这一点与struct相同
  • union可以定义包括构造函数和析构函数在内的成员函数,但是由于union既不能继承自其他类,也不能作为基类使用,所以union中不能含有虚函数
union的定义
union Tocken{
    char   cval;
    int    ival;
    double dval;
};
  • 上述union对象可以保存一个值,这个值的类型可能是char、int、double中的一种
  • union的名字是一个类型名,和其他内置类型一样,默认情况下union是未初始化的,我们可以像显式地初始化聚合类一样使用一对花括号内地初始值显式地初始化一个union
Token first_tocken = {'a'};     //初始化cval成员
Token last_tocken;              //未初始化地Token对象
Token *pt = new Token;         //指向一个未初始化地Token对象的指针

局部类

  • 类可以定义在某个函数的内部,这样的类即局部类
  • 局部类只在定义它的作用域内可见,和嵌套类不同,局部类的成员受到严格限制
  • 局部类的所有成员(包括函数在内)都必须完整定义在类的内部,因此,局部类的作用与嵌套类相比相差很远
  • 在实际编程的过程中,因为局部类的成员必须完整定义在类的内部,所以成员函数的复杂性不能太高,局部类的成员函数一般只有几行代码,否则我们就很难读懂它了
  • 在局部类中不允许声明静态数据成员,因为我们没法定义这样的成员
局部类不能使用函数作用域中的变量
  • 局部类对其外层作用域中名字的访问权限受到很多限制,局部类只能访问外层作用域定义的类型名、静态变量以及枚举成员
  • 如果局部类定义在某个函数内部,则该函数的普通局部变量不能被该局部类使用

固有的不可移植特性

  • 为了支持底层编成,C++定义了一些固有的不可移植的特性
  • 所谓不可移植的特性是指因机器而异的特性,但我们将含有不可移植特性的程序凑够一台机器转移到另一台机器上时,通常需要重新编写该程序
  • 算术类型的大小在不同机器上不一样,这是我们使用过的不可移植特性的一个典型事例
位域
  • 类可以将器(非静态)数据成员定义成位域,在一个域中含有一定数量的二进制位,当一个程序需要向其他程序或硬件设备传递二进制数据时,通常会使用位域
  • 位域在内存中的布局是与机器相关的
  • 位域的类型必须是整型或枚举类型
  • t通常情况下我们使用一个无符号类型保存一个位域
  • 位域的声明形式是在成员名字之后紧跟一个冒号以及一个常量表达式,该表达式用于指定成员所占的二进制位数
Bit mode: 2;
  • 取地址运算符不能用于位域,因此任何指针都无法指向类的位域
  • 通常情况下最后将位域设为无符号类型,存储在带符号类型中的位域的行为将因其具体实现而定
volatitle限定符
  • volatitle的确切含义与机器有关,只能通过阅读编译器文档来理解,要想让使用了volatitle的程序在移植到新机器或新编译器后仍然有效,通常需要对程序进行改变
  • 当对象的值可能在程序的控制或检测之外被改变时,应该将对象声明位volatitle,关键字告诉编译器不对这样的对象进行优化
volatitle int display_register;     //该int值可能发生改变
链接指示:extern"C"
  • C++程序有时需要调用起他语言编写的函数,最常见的时调用C语言编写的函数
  • 像所有其他名字一样,其他语言中的函数名字也必须在C++中进行声明,并且该声明必须指定返回类型和形参列表
  • 对于其他语言编写的函数来说,编译器检查其调用的方式与处理普通C++函数的方式相同,但是生成的代码有所区别
  • C++使用链接指示指出任意非C++函数所用的语言
  • 要想把C++代码和其他语言编写的代码放在一起使用,要求我们必须有权访问该语言的编译器,并且这个编译器与当前的C++编译器是兼容的
//单语句链接指示
extern "C" size_t strlen(const char *);
//复合语句链接指示
extern "C" {
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容