C++编程思想-常量

  • 值替代

     头文件里的const
     	const 是编译属性
     	c++中const默认为内部连接。当定义时,必须赋值。一般const常量没有存储空间。但是 extern 修饰的const会强制进行存储空间分配。(取const地址也要存储空间分配)
     const安全性
     	如果运行期间产生的值初始化一个变量,而且知道在变量的生命周期是不变的,则用const限定该变量。
     const可以用于聚合,然而不能在编译期间使用它的值,因为编译器在编译期间不需要知道存储的内容。
     	const int i[] = {1,2,3,4};
     	// float f(i[3]); // illegal 
     与c语言区别
     	c默认const是外部链接,总是要创建一块内存空间。
     	c++默认const内部连接,创建空间与否依赖于对它如何使用。为了使const成为外部连接,必须明确把它定义成extern。 extern const int x = 1;
     	为什么c++要求一个const定义时必须初始化: 初始化把定义和声明区别开来。
    
  • 指针

     指向const的指针
     	const int* u; // u是一个指针,它指向一个const int。
     const指针
     	使指针本身成为const指针,必须把const 放在*的右边。
     	Int d =1;
     	Int * const w=&d; // w 是一个指针,它是指向int的const指针。
     赋值个类型检查
     	不能把const对象的地址赋给一个非const指针,当然,总能用强制类型转换进行这样的赋值,但是,这是一个不好的习惯。
     	char* cp =“Boston”;//error, 因为字符数组的字面值被编译器作为一个常量字符数组建立的。
     	如果想修改字符串,把它放数组中:
     		char cp[] = "Boston";
    
  • 函数参数和返回值

     传const值: 一般可在函数内用const限定,可以用指针来实现,更好用“引用”
     返回const值:对于内建类型应该去掉const,从而不混淆客户程序员; 对于自定义类型,表明返回的值不能是一个左值(不能被赋值,也不能被修改)
     	临时量自动成为const,这样当程序员犯错误时,会发出警告。
     传递和返回地址:
     	如果传递或者返回一个地址(ptr or ref),客户程序员去取地址并修改其初值是可能的。
     	如果使地址成为const,可以阻止此类事的发生。
     	Alias: 由于引用的语法,可把一个临时对象传递给一个受const引用的函数,但是不能把一个临时对象传递给接受指针的函数--对于指针,它必须明确接收地址。所以一个总是const的临时变量,它的地址可以被传递给一个函数。 这也就是为什么当临时变量按引用传递给一个函数时,这个函数的参数必须是const引用的原因。
    
  •  类内局部const:
     	在这个对象生命周期内,它是一个常量。在ctr list里面为之初始化。
     编译期间类常量:
     	static const: 必须在定义的地方初始化。在该类的所有对象中它都一样。
     	旧版本中用enum hack(无标记的enum)
     		class Bunch
     		{
     			enum{size =100}; // static const int size = 100;
     			Int i[size];
     		}
     整个对象作为const: 引入const成员函数,只能对于const对象调用
     	用户定义类型和内建类型一样,都可以定义一个const对象
     可变的:
     	Bitwise: 每个字节是固定的。
     	Memberwise:整个对象从概念上讲是不变的,但是可以以成员为单位改变。
     	当编译器被告知一个对象是const对象时,它将绝对保护这个对象按位的常量性。
     	当某个对象是const对象时,就指定了应该按位const,但我们可以用某种方法使之改变成按逻辑const
     	方法一被称为“强制转换常量性”const_cast
     	方法二是 使用关键字mutable,以指定一个特定的数据成员可以在一个const对象中改变。
    
  • volatile

     其告诉编译器不要擅自作出有关该数据的任何假设,优化期间尤其如此。
    
C++编程思想,目 录 译者序 前言 第1章 对象的演化 1 1.1 基本概念 1 1.1.1 对象:特性+行为 1 1.1.2 继承:类型关系 1 1.1.3 多态性 2 1.1.4 操作概念:OOP程序像什么 3 1.2 为什么C++会成功 3 1.2.1 较好的C 3 1.2.2 采用渐进的学习方式 4 1.2.3 运行效率 4 1.2.4 系统更容易表达和理解 4 1.2.5 “库”使你事半功倍 4 1.2.6 错误处理 5 1.2.7 大程序设计 5 1.3 方法学介绍 5 1.3.1 复杂性 5 1.3.2 内部原则 6 1.3.3 外部原则 7 1.3.4 对象设计的五个阶段 9 1.3.5 方法承诺什么 10 1.3.6 方法应当提供什么 10 1.4 起草:最小的方法 12 1.4.1 前提 13 1.4.2 高概念 14 1.4.3 论述(treatment) 14 1.4.4 结构化 14 1.4.5 开发 16 1.4.6 重写 17 1.4.7 逻辑 17 1.5 其他方法 17 1.5.1 Booch 18 1.5.2 责任驱动的设计(RDD) 19 1.5.3 对象建模技术(OMT) 19 1.6 为向OOP转变而采取的策略 19 1.6.1 逐步进入OOP 19 1.6.2 管理障碍 20 1.7 小结 21 第2章 数据抽象 22 2.1 声明与定义 22 2.2 一个袖珍C库 23 2.3 放在一起:项目创建工具 29 2.4 什么是非正常 29 2.5 基本对象 30 2.6 什么是对象 34 2.7 抽象数据类型 35 2.8 对象细节 35 2.9 头文件形式 36 2.10 嵌套结构 37 2.11 小结 41 2.12 练习 41 第3章 隐藏实现 42 3.1 设置限制 42 3.2 C++的存取控制 42 3.3 友元 44 3.3.1 嵌套友元 45 3.3.2 它是纯的吗 48 3.4 对象布局 48 3.5 类 48 3.5.1 用存取控制来修改stash 50 3.5.2 用存取控制来修改stack 51 3.6 句柄类(handle classes) 51 3.6.1 可见的实现部分 51 3.6.2 减少重复编译 52 3.7 小结 54 3.8 练习 54 第4章 初始化与清除 55 4.1 用构造函数确保初始化 55 4.2 用析构函数确保清除 56 4.3 清除定义块 58 4.3.1 for循环 59 4.3.2 空间分配 60 4.4 含有构造函数和析构函数的stash 61 4.5 含有构造函数和析构函数的stack 63 4.6 集合初始化 65 4.7 缺省构造函数 67 4.8 小结 68 4.9 练习 68 第5章 函数重载与缺省参数 69 5.1 范围分解 69 5.1.1 用返回值重载 70 5.1.2 安全类型连接 70 5.2 重载的例子 71 5.3 缺省参数 74 5.4 小结 81 5.5 练习 82 第6章 输入输出流介绍 83 6.1 为什么要用输入输出流 83 6.2 解决输入输出流问题 86 6.2.1 预先了解操作符重载 86 6.2.2 插入符与提取符 87 6.2.3 通常用法 88 6.2.4 面向行的输入 90 6.3 文件输入输出流 91 6.4 输入输出流缓冲 93 6.5 在输入输出流中查找 94 6.6 strstreams 96 6.6.1 为用户分配的存储 96 6.6.2 自动存储分配 98 6.7 输出流格式化 100 6.7.1 内部格式化数据 101 6.7.2 例子 102 6.8 格式化操纵算子 106 6.9 建立操纵算子 108 6.10 输入输出流实例 111 6.10.1 代码生成 111 6.10.2 一个简单的数据记录 117 6.11 小结 123 6.12 练习 123 第7章 常量 124 7.1 值替代 124 7.1.1 头文件里的const 124 7.1.2 const的安全性 125 7.1.3 集合 126 7.1.4 与C语言的区别 126 7.2 指针 127 7.2.1 指向const的指针 127 7.2.2 const指针 127 7.2.3 赋值和类型检查 128 7.3 函数参数和返回值 128 7.3.1 传递const值 128 7.3.2 返回const值 129 7.3.3 传递和返回地址 131 7.4 类 133 7.4.1 类里的const和enum 133 7.4.2 编译期间类里的常量 134 7.4.3 const对象和成员函数 136 7.4.4 只读存储能力 139 7.5 可变的(volatile) 140 7.6 小结 141 7.7 练习 141 第8章 内联函数 142 8.1 预处理器的缺陷 142 8.2 内联函数 144 8.2.1 类内部的内联函数 145 8.2.2 存取函数 146 8.3 内联函数和编译器 150 8.3.1 局限性 150 8.3.2 赋值顺序 150 8.3.3 在构造函数和析构函数里隐藏行为 151 8.4 减少混乱 152 8.5 预处理器的特点 153 8.6 改进的错误检查 154 8.7 小结 155 8.8 练习 155 第9章 命名控制 157 9.1 来自C语言中的静态成员 157 9.1.1 函数内部的静态变量 157 9.1.2 控制连接 160 9.1.3 其他的存储类型指定符 161 9.2 名字空间 161 9.2.1 产生一个名字空间 162 9.2.2 使用名字空间 163 9.3 C++中的静态成员 166 9.3.1 定义静态数据成员的存储 166 9.3.2 嵌套类和局部类 168 9.3.3 静态成员函数 169 9.4 静态初始化的依赖因素 171 9.5 转换连接指定 174 9.6 小结 174 9.7 练习 174 第10章 引用和拷贝构造函数 176 10.1 C++中的指针 176 10.2 C++中的引用 176 10.2.1 函数中的引用 177 10.2.2 参数传递准则 178 10.3 拷贝构造函数 179 10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值