《C++笔记 第一部分 C++语言篇》第3章 内存模型及名字空间

2024-08-30 13:08

本文主要是介绍《C++笔记 第一部分 C++语言篇》第3章 内存模型及名字空间,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3.1作用域

 作用域(scope)描述了一个名字在文件(编译单元)的多大范围内可见。

 C++支持三种形式的域:

  •  局部域(local scope)
    局部域是包含在函数定义或者函数块中的程序文本部分。
  •  名字空间域(namespace scope)
    名字空间域是不包含在函数声明函数定义或者类定义内的程序文本部分
    程序的最外层的名字空间域被称作全局域(global scope),或全局名字空间域(global namespace scope)
    对象函数类型以及模板都可以在全局域中定义
    可以利用名字空间定义namespace definition 来定义用户声明的user-declared 的名字空间。每个用户声明的名字空间都是一个不同的域,它们都与全局域不同,与全局域相同的是用户声明的名字空间可以包含对象函数类型和模板的声明与定义,以及被嵌套其内的用户声明的名字空间。
  •  类域(class scope)
    每个类定义都引入了一个独立的类域

 变量的作用域

  •  局部变量的作用域为局部,仅能在代码块内可见
  •  "{}"就是代码块的作用域,函数、switch、for、while,等等
  •  全局变量的作用域为全局的,在定义处开始直到文件尾可见
  •  自动变量的作用域是局部的,静态变量的作用域要看其定义位置
  •  函数原型作用域
    在函数原型声明时候,在"()“内声明的参数列表中的变量,仅能在”()"内可见。正因为如此,所以函数声明时,有无形参,形参是什么都不重要。
  •  名字空间作用域
    在指定名字空间中定义的变量,在整个名字空间中可见。
  •  类作用域
    类中声明的变量,在整个类内部可见,不管是什么权限的变量。

 函数的作用域
可以是整个类,也可以是整个名字空间,但不能是局部的。

3.2链接性及存储性

链接性(linkage)描述了名称如何在各个单元中的共享。
外部链接:是指名称可以在文件间共享
内部链接:名称仅仅能在一个文件中的函数共享
变量的链接性及存储性(下表):

表1

在这里插入图片描述
 变量的说明限定符
auto(C++11中没有)、register、static、extern、thread_local(C++11新增)、mutable、const、volatile

 函数的链接性及存储性
函数的存储持续性为静态的
默认的情况下,函数的链接性为外部的
要引用函数,可以加extern说明限定符
加static说明限定符的函数,链接性为内部的;如果和外部的函数重名,则静态的函数替换之。
非内联函数受单定义规则限制,但是内联函数则不然。C++运行内联函数的定义放在头文件内。不过一个内联函数所有的定义必须相同。

 语言链接性
对于函数或变量而言,只要有链接性,则每种编程语言,都有自己的规则来处理它们的名字。这个就是语言的链接性。
如果C语言编写的函数需要被C++代码使用到,就要注意到语言的链接性。

extern "C" void spiff(int);//use C protocol for name look-up
extern void spoff(int);//use C++ protocol for name look-up
extern "C++"void spaff(int);//use C++ protocol for name look-up

3.3动态内存

变量的5种存储方案(线程内存除外)中仅仅描述了自动存储和静态存储,并没有说明动态存储的情况。C中malloc/free分配管理的堆区就是动态内存,C++中则引入了运算符new/delete来分配内存。

运算符new可以动态创建对象,创建对象后会返回对象的地址。如果内存不足导致车无法成功创建对象,则归返回一个空指针。
动态创建的对象要用“delete对象指针”才能销毁对象;
运算符符new和new[]调用的函数如下:

void *operator new (std :: size_t);//used by new
void *operator new[] (std :: size_t);//used by new[]

运算符符delete和delete[]调用的函数如下:

void operator delete(void *);
void operator delete[] (void *);

定位new运算符:

int *p2 = new(buffer) int;
invokes new(sizeof(int),buffer );

例子:用Box类创建对象

Box *pt1;
pt1 = new Box;//创建对象
delete pt1;//销毁对象
Box *pt1= new Box(32);//创建对象
Box *pt;
pt = new Box;//创建对象
if(pt != NULL)
{delete pt;pt = NULL; 
}

3.4声明区与作用域

 C++标准的名字空间属性
声明区:可以进行声明的区域
潜在的作用域:变量潜在的作用域,从声明点,到声明区结尾

 变量并非在潜在的作用域内都可见,只要存在嵌套声明区,且和内部声明区的变量重名,则会被内部声明区的变量隐藏

 每个声明区都可以声明名称,且相互独立。也就意味着,即使不同声明区的出现了同名,也不会发送冲突。

在这里插入图片描述

3.5引用

引用是变量的别名,,不会再开辟空间。引用在实计开发中,只使用于函数的形式参数。比喻:引用是一种受限指针。引用能做的事指针都能做,而指针能做事引用不一定能用。引用的底层实现多数编译器也是指针.

#include <iostream>
using namespace std;void f1() {int a = 20;int &b = a;//创建引用类型变量时,要立刻 "赋值"int c = 100;b = c;cout<<b<<endl;//100cout<<a<<endl;//100cout<<&a<<endl;// 0x7fffcaa6ca10cout<<&b<<endl;// 0x7fffcaa6ca10
}void f2(int *p) {*p = 21;
}void f3(int &r) {//int &r = ager = 22; //age=22
}int main() {
f1();int age = 20;//调用函数,让age的值改变为21f2(&age);cout<<"age="<<age<<endl;//age=21//调用函数,让age的值改变为22; 但是不能使用指针f3(age);cout<<"age="<<age<<endl;//age=22return 0;
}

结果如下所示:

在这里插入图片描述

3.6名字空间

 命名声明区
namespace 名称{
//声明区
}

 使用名称空间

 声明的话,则直接使用
using 名称::变量
using 名称::函数名

 不声明的话
名称::变量或函数名

参考代码

fs.cpp文件

#include "fs.h"namespace fs1
{namespace one204{void test(){}}void show1() {}void show() {}void Stu::study(){}}namespace fs2
{void show2(){}void show(){}void Stu::sleep(){}
}

fs.h文件

#ifndef FS_H_
#define FS_H_namespace fs1
{namespace one204{void test();}void show1();void show();class Stu{public:void study();};
}namespace fs2
{void show2();void show();class Stu{public:void sleep();};
}
#endif /* FS_H_ */

main.cpp文件

/********************************************************************************* @file    		main.cpp* @author  		BruceOu* @version 		V1.0* @date    		2019.03.03* @brief          命名空间*******************************************************************************/
/**Includes*********************************************************************/
#include <iostream>
#include "fs.h"/**namespace********************************************************************/
//using namespace std;
using namespace fs1::one204;
using namespace fs1;
using namespace fs2;/*** @brief     主函数* @param     argcargv* @retval    None*/
int main(int argc, char *argv[])
{std::cout<<"fsdfsd"<<std::endl;fs1::one204::test();fs1::one204::test();fs1::show1();fs1::show();fs2::show();fs1::Stu stu;stu.study();fs2::Stu stu2;stu2.sleep();show2();return 0;
}

这篇关于《C++笔记 第一部分 C++语言篇》第3章 内存模型及名字空间的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120910

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Linux命令rm如何删除名字以“-”开头的文件

《Linux命令rm如何删除名字以“-”开头的文件》Linux中,命令的解析机制非常灵活,它会根据命令的开头字符来判断是否需要执行命令选项,对于文件操作命令(如rm、ls等),系统默认会将命令开头的某... 目录先搞懂:为啥“-”开头的文件删不掉?两种超简单的删除方法(小白也能学会)方法1:用“--”分隔命

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

C++中处理文本数据char与string的终极对比指南

《C++中处理文本数据char与string的终极对比指南》在C++编程中char和string是两种用于处理字符数据的类型,但它们在使用方式和功能上有显著的不同,:本文主要介绍C++中处理文本数... 目录1. 基本定义与本质2. 内存管理3. 操作与功能4. 性能特点5. 使用场景6. 相互转换核心区别

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块