《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; } 上边的代码 ...
随机推荐
- Java简单的RPC实现(一)
RPC使用java最基本的,传输层使用Socket,序列化使用Serializable,java 动态代理模式,但是未实现消息注册等相关信息 大道至简 server端 package com.rpc. ...
- yum安装 指定安装目录
yum -c /etc/yum.conf --installroot=/usr/local --releasever=/ install love
- npm run build之后生成的dist如何扔到服务器运行(npm run build之后如何本地运行)
运行npm run build之后,会生成一个dist文件夹,里面的目录结构大概是这样的: 生成完的文件我们怎么来运行呢?直接在本地打开inde.html是无法运行的,打包的时候有提示: 构建文件应该 ...
- out参数ref参数params 可变参数
1.我们在主函数中调用其他函数,我们管主函数为调用者,其他函数为被调用者. 如果被调用者,想要得到调用者的值:传参 使用静态字段来模拟全局变量 在方法外类里写字段 public static _na ...
- Winform无边框窗体拖动
调用示例 当然,BUG还是有的,不过基本需求倒也可以
- google自定义广告系列
Part1:说明 向网址添加参数以标识引荐流量的广告系列. 通过向在广告系列中使用的目标网址添加广告系列参数,您可以收集这些广告系列整体效果的相关信息,还可以了解广告系列在何处投放时效果更好.例如,您 ...
- MySQL7:性能优化
性能优化 优化MySQL数据库是数据库管理员和数据库开发人员的必备技能.MySQL优化,一方面是找出系统的瓶颈,提高MySQL数据库的整体性能:一方面需要合理的结构设计和参数调整,以提高用户操作响应的 ...
- Android Studio 1.1.0汉化初步出炉!
我找到去年12月国人汉化的版本,然后迁移上来的.实测支持Android window最新版(1.1.0) 项目分4部分:1压缩好的:2文本分析器:3原生的语言包:4原版语言包备份 现在一些新增的项目没 ...
- java并发编程的艺术(一)---锁的基本属性
本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...
- 控制台直接执行sql语句
mysql -h127.0.0.1 -P3306 -uroot -paaccccccc databasename -e "select * from RegInfo where Plat ! ...