《C++ Primer Plus(第六版)》(13)(第九章 内存模型和命名空间 笔记)
1.为了保持通用性,C++使用术语翻译单元,而不是文件,文件不是计算机组织信息时的唯一方式。
2.C++允许编译器使用自己的名称修饰,因此不同的编译器编译出来的二进制模块(对象代码文件),通常是无法链接的。
3.
自动存储持续性:代码块内局部的变量,走过了就自动消失了。
静态存储持续性:程序员了,就一直存在,直到程序结束。起作用域看声明的位置。
线程存储持续性:并行编程用到,使用tread_local声明,则与线程同寿了。
动态存储持续性:用new来分配的内存,直到delete才回收。
4.在C++旧版本和C中,auto是用于显示声明自动存储的。但是因为自动存储在局部变量中是默认的,所以几乎没人使用。
在C++11之后auto这样的用法被删掉了,改成自动类型推断。
5.自动存储被放在栈中。
栈是用来对自动变量进行管理,之所以成为栈,就是新数据被象征性放在原有数据的上面。
栈是后进先出的。
栈使用两个指针,一个在底部,一个在顶部,上面的数据没用之后,顶部指针向下移动,之前的位置上的内容就不再被标记,但是没有删除的。
当下一个数据放入栈中的时候,就会覆盖刚刚的内容。
6.静态存储的变量,因为一直存在,所以编译器分配了固定的位置给它们。变量的每个元素或成员的默认值都是0。
7.内部链接和外部链接的问题。
先看看代码:
main.cpp
#include "Test.h" #include <iostream> using namespace std; extern int test; extern int test2; void tttttt() { cout << test << endl; cout << test2 << endl; }Test.h
#ifndef _Test_H_ #define _Test_H_ void tttttt(); #endifTest.cpp
#include "Test.h" #include <iostream> using namespace std; extern int test; extern int test2; void tttttt() { cout << test << endl; cout << test2 << endl; }
在main.cpp里面声明了静态变量test,和test2.只有test2用了static。
在Test.cpp中是无法直接使用的。
所以使用了外部声明。但是因为test是外部链接的,所以能链接上。
而test2是内部链接的。链接不上,实际上,编译的时候会报错:
1>------ 已启动生成: 项目: CppPrimer, 配置: Debug Win32 ------ 1> main.cpp 1> Test.cpp 1> 正在生成代码... 1>Test.obj : error LNK2001: 无法解析的外部符号 "int test2" (?test2@@3HA) 1>E:\mywokespace\CppGame\Debug\CppPrimer.exe : fatal error LNK1120: 1 个无法解析的外部命令 ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
9.存储说明符
auto(C++11中已经不是说明符了)
register(C++11以前是指示寄存器存储,C++11之后就是显式支出自动变量)
static:静态存储
extern:外部变量
thread_local:线程变量,C++11新增的,可以与static或extern一起使用
mutable:声明这样的成员,表示即使变量为const,其属性也可以改变
cv-限定符:
const:常量
volatile:中文意思是可变的,多变的,声明了这个关键字的变量,可能即使不对其进行修改,其本身也会产生变化。
声明了volatile的变量,将不再放在寄存器中进行访问优化。
10.使用外部C语言库的时候,引用他们的函数可以用extern
extern "C" void spiff(int);
即使是同一个编译器,编译出的C和C++的链接语言也可能不同。因为C中没有重载,C++有重载,所以函数名肯定要复杂多。
11.通常编译器使用三块独立的内存:静态变量,自动变量(栈),动态变量(堆)。
12.using可以指定使用命名空间,可以指定使用命名空间中的某个属性。
#include <iostream> #include <array> #include <string> #include <set> //#include "test.h" using namespace std;//使用命名空间 namespace FableGame { int test = 1; } int test = 2; int main() { using FableGame::test;//使用某个属性 cout << test << endl;//1 cout << ::test << endl;//2 std::cin.get(); std::cin.get(); return 0; }
13.可以给名称空间创建别名,例如:
namespace a {}; namespace b = a;