《C++ Primer Plus》读书笔记之七—内存模型和名称空间
第九章 内存模型和名称空间
1、不要将函数定义或者变量声明放到头文件中。
2、头文件常包含的内容:函数原型、使用#define或者const定义的常量、结构声明、类声明、模板声明、内联函数。
3、避免多次包含同一个头文件的技术:#ifndef/#endif。仅当以前没有使用预处理器编译指令#define定义一个头文件名称时,才处理#ifndef和#endif之间的语句。
4、链接性描述了名称如何在不同单元间共享。链接性为外部的名称可在文件间共享,链接性为内部的名称只能由一个文件中的函数共享。自动变量(函数定义中声明的变量(包括函数参数))的名称没有链接性,因为它们不能共享,作用域为局部。
5、常用的管理自动变量的方法是留出一段内存,并将其视为栈,以管理变量的增减。栈的默认长度取决于实现,但编译器通常提供改变栈长度的选项。程序使用两个指针来跟踪栈,一个指向栈底,另一个指向栈顶,即下一个可用的内存单元。函数结束时,栈顶指针被重置为函数被调用前的值,从而释放新变量使用的内存。新变量没有被删除,但不再被标记,它们所占用的空间被下一个将值加入到栈中的函数所使用。
6、C++支持使用register关键字来声明局部变量,说明该变量将被频繁使用。寄存器变量是另一种形式的自动变量。CPU访问寄存器中的值的速度比访问栈中的内存快。但编译器不一定会满足此声明。注:在寄存器中的变量没有内存地址,因此不能将地址操作符用于寄存器变量。
7、C++为静态存储持续性变量提供三种链接性:外部、内部和无链接性。这三种链接性都在整个程序执行期间存在,与自动变量相比,它们的寿命更长。编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存在。
8、链接性为外部的静态持续变量:必须在代码块的外面声明它,可以在程序的其他文件中使用它,即在其他文件中用extern对该变量进行引用声明,而且只有一个文件包含了该变量的外部定义;链接性为内部的静态持续变量:必须在代码块的外面声明它,并使用static限定符,表明该变量只能在其所属的文件中使用;无链接性静态持续变量:必须在代码块内声明它,并使用static限定符,这意味着虽然该变量只在该代码块中可用,但它在该代码块不处于活动时仍然存在。例子如下:
...
int global=1000; // 链接性为外部的静态变量
static int one_file=50; // 链接性为内部的静态变量
int main()
{
...
}
void fun1(int n)
{
static int count=0; // 无链接性静态持续变量
}
9、定义与全局变量同名的局部变量后,局部变量将隐藏全局变量。当将(::)放在变量名称前面时,该操作符表示使用变量的全局版本。
10、应使用链接性为外部的静态持续变量在多文件程序的不同部分之间共享数据;应使用链接性为内部的静态持续变量在同一个文件的多个函数之间共享数据。
11、如果初始化了 静态局部变量,则程序只在启动时进行一次初始化。以后再调用函数时,将不会像自动变量那样再次被初始化。
12、volatile关键字表明,即使程序代码没有对内存单元进行修改,其值也可能发生变化。它的作用时为了改善编译器的优化能力。如果不将变量声明为volatile,则编译器将进行这种优化;将变量声明为volatile,相当于告诉编译器,不要进行这种优化。
13、mutable用来指出,即使结构(或类)变量为const,其某个成员也可以被修改。
14、默认情况下全局变量的链接性为外部的,但const全局变量的链接性为内部的(就像使用了static说明符一样)。如果希望某个常量的链接性为外部的,则可以使用extern来覆盖默认的内部链接性。如:extern const int a=1;
15、C++不允许在一个函数中定义另外一个函数,因此所有函数的存储持续性都自动是静态的,即整个程序执行期间都一直存在。在默认情况下,函数的链接性为外部的,即可以在文件间共享。也可以用static将函数的链接性设置为内部的,使之只能在一个文件中使用,必须同时在原型和函数定义中使用该关键字。
16、对于非内联函数,程序中只能包含一个定义。
17、C语言链接性:在C语言中,一个名称只对应一个函数。C语言编译器可能将fun这样的函数名翻译为_fun。C++语言链接性:C++中,同一个名称可能对应多个函数,必须将这些函数翻译为不同的符号名称。
18、如果在C++程序中使用C库中预编译的函数,为了解决名字的匹配问题,可以用函数原型来指出要使用的命名约定:
extern “C” void fun(); // 使用C语言链接性
extern void fun(); // 使用C++语言链接性
extern “C++” void fun(); // 使用C++语言链接性
19、使用new来设置指针的语句必须位于函数中,这是因为只能使用常量表达式来初始化静态存储变量。
20、布局new操作符:指定要使用的位置。例子:
char buffer[500];
int *p;
p=new (buffer) int[20]; // 从buffer中分配空间给一个包含20个元素的int数组。
注:buffer指定的是静态内存,而delete只能用于这样的指针:指向常规new操作符分配的堆内存。也就是说,数组buffer位于delete的管辖区之外。所以不用delete来释放使用new操作符分配的内存。
21、声明区域:可以在其中进行声明的区域。潜在作用域:从声明点开始,到其声明区域的结尾。因此潜在作用域比声明区域小,这是由于变量必须定义后才能使用。
22、名称空间可以是全局的,也可以位于另一个名称空间中,但不能位于代码块中。在默认情况下,在名称空间中声明的名称的链接性是外部的(除非它引用了常量)。
23、任何名称空间中的名称都不会与其他名称空间中的名称发生冲突。
24、通过作用域解析操作符(::)来访问名称空间的名称。
25、using声明使特定的标识符可用,using编译指令使整个名称空间可用。
26、注:假设名称空间和声明区域定义了相同的名称。如果试图使用using声明将名称空间的名称导入该声明区域,则这两个名称会发生冲突,从而出错。如果使用using编译指令将名称空间的名称导入该声明区域,则局部版本将隐藏名称空间不版本。
27、一般来说,使用using声明比使用using编译指令更安全,这是由于它只导入指定的名称。如果该名称与局部名称发生冲突,编译器将发出指示。using编译指令导入所有名称,包括可能不需要的名称。如果与局部名称发生冲突,则局部名称将覆盖名称空间的版本,而编译器并不会发出警告。
28、名称空间的其他特性:
①namespace A
{
namespace B
{
int a;
...
}
}
访问a的话:A::B::a。也可以使用using编译指令使内部的名称可用:using namespace A::B;②另外,也可以在名称空间中使用using编译指令和using声明:
namespace myth
{
using Jill::fetch;
using namespace element;
using std::cout;
using std::cin;
}
访问Jill::fetch,可以这样:std::cin>>myth::fetch;也可以这样:std::cout<<Jill::fetch;
using namespace myth;(添加了element名称空间)和using namespace myth;using namespace element;等价。
③可以给名称空间创建别名。namespace my_love{...}; namespace ml=my_love;
29、不能在未命名名称空间所属文件之外的其他文件中,使用该名称空间中的名称,因此这种方法可以替代链接性为内部的静态变量。例如:
static int one_file; // 链接性为内部的静态变量
int main()
{
...
}
可以这样:
namespace
{
int one_file; // 链接性为内部的静态变量
}
int main()
{
...
}
30、在名称空间中声明的函数名的作用域为整个名称空间,因此定义和声明必须位于同一个名称空间中。
《C++ Primer Plus》读书笔记之七—内存模型和名称空间的更多相关文章
- C++ primer plus读书笔记——第9章 内存模型和名称空间
第9章 内存模型和名称空间 1. 头文件常包含的内容: 函数原型. 使用#define或const定义的符号常量. 结构声明. 类声明. 模板声明. 内联函数. 2. 如果文件名被包含在尖括号中,则C ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- 《C++ Primer Plus》第9章 内存模型和名称空间 学习笔记
C++鼓励程序员在开发程序时使用多个文件.一种有效的组织策略是,使用头文件来定义用户类型,为操纵用户类型的函数提供函数原型,并将函数定义放在一个独立的源代码文件中.头文件和源代码文件一起定义和实现了用 ...
- 深入理解Java虚拟机读书笔记8----Java内存模型与线程
八 Java内存模型与线程 1 Java内存模型 ---主要目标:定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节. ---此处的变量和J ...
- 《java并发编程实战》读书笔记13--Java内存模型,重排序,Happens-Before
第16章 Java内存模型 终于看到这本书的最后一章了,嘿嘿,以后把这本书的英文版再翻翻.这本书中尽可能回避了java内存模型(JMM)的底层细节,而将重点放在一些高层设计问题,例如安全发布,同步策略 ...
- [C++ Primer Plus] 第9章、内存模型和名称空间(一)程序清单
程序清单9.9(静态存储连续性.无链接性) #include<iostream> using namespace std; ; void strcount(const char *str) ...
- (8)C++ 内存模型与名称空间
一.单独编译 头文件 不要将函数定义或者变量声明放到头文件中,引入多个文件时可能会造成同一个函数定义多次 引入头文件 #include "文件名" File1.h #ifndef ...
- 《C++ Primer Plus 6th》读书笔记 - 第九章 内存模型和名称空间
1. 单独编译 1.1 头文件中常包含的内容: 函数原型 使用#define或const定义的符号常量 结构声明 类声明 模板声明 内联声明 1.2 只需将源代码文件加入到项目中,而不用加入头文件.这 ...
- C++ Primer Plus读书笔记(九)内存模型和名称空间
1.作用域和链接 int num3; static int num4; int main() { } void func1() { static int num1; int num2; } 上边的代码 ...
随机推荐
- 在Docker平台实现MySQL Replication(复制)
MySQL Replication提供了数据库之间复制数据的功能,通过这个功能可以让一个数据库的数据更改自动同步到另外一个数据库.通常用这个功能来实现数据备份.数据容灾.数据冗余,进一步实现数据的读写 ...
- git常用命令小记
git status 查看缓存区和工作区的状态 +表示N个新文件 ~表示N个修改 -表示N个删除 两组的时候前面的是暂存区,后面的是工作区 git add fileName 变更文件状态(工作区--& ...
- can/socket can
1. 概念 参考:Linux-CAN编程详解 can引脚: cn2: 15:CAN1_H 19 CAN1_L 根据每组报文开头的 11 位标识符(扩展帧为29位标识符.CAN 2.0A 规范)解释数据 ...
- 触摸UITextView找到该触摸点的文字
参加了一个比赛有一道题是如标题一样,在UITextView上触摸找到该触摸点对应的文字,比赛也可以查资料,当时做的时候就是抱着玩玩的心态试试也没认真做,就没查就去吃饭去了,昨晚下班回去在思考这个问题发 ...
- 二维码之qrencode生成(带logo)
从github下载的qrencode没有QRCodeGenerator文件,需要引入 // // QR Code Generator - generates UIImage from NSString ...
- 3.C#基础篇-->堆和栈
一.前言 堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不 ...
- [IDE]快捷键整理
VS Resharper eclipse 备注 运行 Ctrl+F5 - Ctrl+F11 调试 F5 - F11 逐语句执行 F11 - F5 IE.FF: F11 逐过程执行 F10 ...
- SpringMVC 工作原理详解
本文Github开源项目https://github.com/Snailclimb/JavaGuide,只供自己学习总结无商业用途,如有侵权,联系删除 先来看一下什么是 MVC 模式 MVC 是一种设 ...
- java并发编程的艺术(三)---lock源码
本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...
- xamarin.Android ImageView 异步加载网络图片
/// <summary> /// 异步获取文件流 /// </summary> /// <param name="url"></para ...