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

头文件中长包含的内容:

1. 函数原型

2. 使用#define或const定义的符号常量

3. 结构声明

4. 类声明

5. 模板声明

6. 内联函数的定义

C++存储方式是通过存储持续性、作用域和链接性来描述的。

编译器将分配固定的内存块来存储静态存储持续性变量,这些变量在整个程序执行期间一直存在。

如果没有显式地初始化静态变量,编译器将把它设置为0。

在代码块外部声明的变量默认为静态变量(使用static限定符修饰的变量链接性为内部,否则为外部);

在代码块内部声明的变量默认为自动变量(使用static限定符修饰,使其变为静态变量,无链接性,作用域)。

使用关键字extern来声明以前定义过的外部变量。

相对于局部的自动变量,外部变量也称为全局变量。

在局部变量名前使用作用域解析运算符"::",表示使用其全局版本。

存储说明符:

auto(在C++11中不再是说明符)

register(寄存器存储的自动变量)

static

extern

thread_local(C++11新增)

mutable(被其修饰的变量所在的结构体(或类)变量即使是const,此变量也能被修改)

C-V限定符

const(const全局变量的链接性为内部)

若程序员希望某个常量的链接性为外部,则可以使用关键字extern来覆盖默认的内部链接性。

volatile(若不将变量声明为volatile,编译器会将变量存储在寄存器中,这样保证了程序在多次调用同一变量后变量值不会发生变化(可能被硬件修改或多个程序共享数据);

若将变量声明为volatile,编译器将不会进行这种优化)

函数的内存模型

所有函数的存储性都默认为静态的,链接性为外部的。

可以使用关键字extern和static来限定函数的链接性。

单定义规则规定在多文件程序中,只能有一个相同函数的定义;

但内联函数不受此限制(但C++要求一个函数的所有内联定义都必须相同),内联函数可以在程序的多个文件中重复定义。

编译器先在程序文件中搜索函数定义,之后再到库中搜索。

语言链接性

语言链接性为另一种形式的链接性。链接程序要求每个不同的函数都有不同的符号名。

在C++中,同一个名称可能对应多个函数,必须将这些函数解释成不同的符号名称。

C++编译器执行名称校正或名称修饰,为重载函数生成不同的符号名称。

C语言链接性C++语言链接性存在差异,

如果要在C++中使用C库中的预编译函数,可以使用函数原型来指出要使用的约定:

extern "C" void spiff(int);  //指出使用C库中的函数spiff()
extern void spiff(int);      //默认使用C++库
extern "C++" void spiff(int);//使用C++库

动态分配

使用new运算符初始化:

1. 为内置的标量类型分配空间并初始化

int *pi = new int (6);
int *pj = new double (6.666);

2. 初始化常规结构或数组(需要用大括号)

struct where 
{
    double x;
    double y;
    double z;     
}

where* pi = new where {28.1, 33,4, 52.1};//C++11

int *pj = new int [3] {1, 2, 3};//C++11

同样,列表也可用于单值初始化。

new失败时将引发异常std::bad_alloc。

new和new []运算符分别调用如下函数:

void* operator new(std::size_t);//void* 是空指针;std::size_t对应于合适的整型
void* operator new [] (std::size_t);

这些函数称作分配函数(alloction function)。

new运算符的一种变体称为定位new运算符,使用前必须包含头文件new。

名称空间

使用关键字namespace创建名称空间,默认情况下,名称空间中声明的名称的链接性为外部

名称空间允许嵌套。

可以给名称空间创建别名:

namespace mfc = my_favorite_city;//让mfc成为my_favorite_city的别名

未命名名称空间的链接性为内部。

原文地址:https://www.cnblogs.com/sungnox/p/7616841.html