C++ Primer Plus 第九章 内存模型与名称空间

1 篇文章 0 订阅
1 篇文章 0 订阅

第九章 内存模型和名称空间

9.1单独编译

1.程序组成

(1)头文件:存放结构声明、函数原型
(2)源代码文件:与结构有关的函数代码(处理结构)
(3)源代码文件:调用与结构有关的函数的代码

2.头文件应该存放

(1)使用 #defineconst 定义的符号常量
(2)结构声明
(3)类声明
(4)模板声明
(5)函数原型
(6)内联函数

3.头文件<> 与 ""区别

  <>:优先在存储头文件的主机系统的文件系统进行查找;
  “”:优先在当前工作目录或源代码目录中查找;

4.避免多次包含同一文件技巧

#ifndef COORDIN_H_
#define COORDIN_H_

...
#endif

9.2存储持续性、作用域和链接性

1.局部变量、静态变量、全局变量、动态内存变量

变量类型存储时间作用域链接性内存位置关键字
局部变量块内块内内部无/register
局部静态变量程序运行期间块内内部全局区static
全局静态变量程序运行期间当前文件内部全局区static
全局变量程序运行期间多个文件外部全局区声明时使用extern
动态内存变量---new/delete

注: 变量隐藏:局部变量会隐藏掉全局变量;静态变量隐藏常规外部变量;等

**链接性:**描述名称在不同单元间的共享,包含内部和外部;
内部:表示单个文件的函数共享;
外部:表示可在文件间共享;
内部链接性:表示每个文件都可以拥有一组属于自己的常量;

链接性与作用域表示的涵义一致:内部 <-> 当前文件; 外部 <-> 多个文件;

2.说明符和限定符

说明符涵义
auto(C++11中)自动类型推断
register显示指出局部变量
static静态变量
extern声明引用在其他地方定义的变量
thread_local指出变量的持续性与所属线程的持续性相同
mutable指出即使结构(或类)变量为const,其某个成员也可被修改

注:
1)全局const定义等同于static;例const int fingers = 100;(内部性链接)
2)extern可覆盖全局const定义;例extern const int fingers = 100;(外部性链接)

3.函数和链接性

  默认情况下,函数的链接是外部的,可多个文件共享;
  使用static可将函数的链接性变为内部,单个文件使用。

4.语言链接性

  extern "C":使用C语言链接协议
  extern "C++":使用C++语言链接协议

5.new - 动态内存

1)使用new运算符初始化:分配内存空间并初始化
  例:int *pd = new int(6);
  例:where *pd = new where{12.0,13.0,2.5};(where是strut结构)
2)new失败
  发送异常std::bad_alloc
3)new 和 new[]
  void * operator new(std::size_t)
  void * operator new[](std::size_t)

  int *pt = new int; 等价于 int *pt = new int(sizeof(int))
4)定位new运算符
  特性:可指定要使用的位置

char buffer[100];  
int *p1 = new (buffer) int[20];  

  释:将p1放到buffer对应的内存位置

注: delete只能用于常规new运算符分配的堆内存。

9.3名称空间

1.定义

namespace Jack {
	double pail;
	void fetch();
}

位置:全局 或 另一名称空间中,不可位于代码块中
包含:用户定义的名称空间 以及 全局命名空间(全局变量位于此)

" :: " :作用域解析运算符

1.using声明和using编译指令

1)using声明:由被限定的名称和它前面的关键字using组成
  using Jack::fetch;
2)using编译指令:由名称空间名和它前面的关键字using namespase
  using namespace Jack
3)比较:
  (1)假设名称空间和声明区域定义了相同的名称:using声明导入,会发生冲突;using编译指令导入,局部变量会将名称空间版本隐藏;
  (2)using声明比using编译指令更安全;

2.名称空间的其他特性

namespace myth
{
	namespace fire //嵌套
	{
		int flame;
		...
	} 
	using Jill::fetch;       //使用using声明
	using namespace elements;//使用using编译指令
	using std::cout;
}

1)嵌套访问:myth::fire::flame

2)using编译指令可传递
  using namespace myth:就可使用到elements中的内容

3)别名

namespace MEF = myth::elements;

4)未命名的名称空间 等价于 静态变量

3.示例

namespace Jill{
	double bucket(double n){..}
	double fetch;
	struct Hill{..};
}
char fetch;
int main()
{
	using Jill::fetch; //put fetch into local namespace
	double fetch;	   //Error! 
	cin >> fetch;	   //读取一个值到Jill::fetch
	cin >> ::fetch;	   //读取一个值到全局变量fetch
	...
}  

::fetch 全局名称空间中的变量

4.指导原则

  • 使用已命名的名称空间中声明的变量,而不是使用外部全局变量/静态全局变量;
  • 若开发了一个函数库或类库,将其放在一个名称空间中;
  • 仅将编译指令using作为一种将旧代码转换为使用名称空间的权宜之计;
  • 不在头文件中使用using编译指令,若非要使用,应将其放在所有预处理器编译指令#include之后;
  • 导入时,首选using声明;
  • 对于using声明,首选将其作用于设置为局部而不是全局;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值