cpp primer plus笔记07-内存模型和命名空间

本文介绍了C++中变量的作用域规则,强调了全局、局部变量的区别,以及静态变量和链接性。同时讲解了命名空间的概念及其使用,以及new运算符在内存分配和管理中的特殊用法。
摘要由CSDN通过智能技术生成
  1. 对于相同变量名的变量,CPP会覆盖作用域大的变量,而使用作用域小的变量,如果想在函数体内使用全局的变量可以在变量名前加上::加以区分,比如warm=3会使得局部的warm变量等于3,而::warm=3会使得全局的warm=3 。
  2. 存储描述持续性作用域链接性声明举例
    自动变量自动代码块在代码块函数中int a = 0;
    静态,无链接性变量静态代码块在代码块函数中,使用关键字staticstatic int a = 0;(函数体内)
    静态,外部链接性变量静态文件外部不在任何函数内,放置在全局int a = 0;(全局)
    静态,内部链接性变量静态文件内部不在任何函数内,使用static声明static int a = 0;(全局)
3. 静态外部链接性变量可以在不同文件中使用,但是只能有一个文件定义一个该变量,其他文件必须使用关键字extern声明改变量,例如extern int a;相同的变量名放置在不同文件全局,如果不使用以上方法的话,只能设置为一个是外部链接和一个是内部链接的变量。 4. 命名空间注意点: 命名空间可以是全局的,也可以位于另一个命名空间。
	namespace element
	{
		namespace fire
		{
			int flame;
		}
		int water
	}

命名空间具有传递性,如下图using namespace myth;等于using namespace elemet;加上using namespace myth;

	namespace myth
	{
		using std::cout;
		using std::cin;
		using namespace element;		
	}

可以给命名空间建立别名

	namespace myth=very_myth_namespace;

可以通过一下方式简化对于嵌套命名空间的使用

	namespace MEFF=myth::element::fire;
	using MEF::flame;

可以使用没有名字的命名空间

	namespace 
	{
		int ice;
	}

可以在不同文件对同一命名空间添加相关数据,但是,但是如果有文件没有包含某个文件,但是包含其他和该文件一样命名空间的文件,那么是不能使用该文件的相关数据的。
5. 定位new运算符可以从程序员选择的指定位置分配一块空间给变量,其作用是设置该变量的内存管理规程,处理需要通过特定地址进行访问的硬件或者在特定位置创建对象。

	#include<iostream>
	#include<new>
	const int BUF = 512;
	const int N = 5;
	char buffer[BUF];
	int main()
	{
		double* pd1, * pd2;
		int i;
		pd1 = new double[N];
		pd2 = new (buffer) double[N];
		for (int i = 0; i < N; ++i)
		{
			pd2[i] = pd1[i] = 1000 + 20.0 * i;
		}
		std::cout << "Memory addresses:\n";
		std::cout << "heap: " << pd1 << " static:" << (void*)buffer << std::endl;
		std::cout << "Memory contents:\n";
		for (int i = 0; i < N; ++i)
		{
			std::cout << pd1[i] << " at " << &pd1[i] << "; ";
			std::cout << pd2[i] << " at " << &pd2[i] << std::endl;
		}
		double* pd3, * pd4;
		pd3 = new double[N];
		pd4 = new (buffer) double[N];
		for (int i = 0; i < N; ++i)
		{
			pd3[i] = pd4[i] = 1000 + 40.0 * i;
		}
		std::cout << "Memory contents:\n";
		for (int i = 0; i < N; ++i)
		{
			std::cout << pd3[i] << " at " << &pd3[i] << "; ";
			std::cout << pd4[i] << " at " << &pd4[i] << std::endl;
		}
		delete[] pd1;
		pd1 = new double[N];
		pd2 = new (buffer + N * sizeof(double)) double[N];
		for (int i = 0; i < N; ++i)
			pd2[i] = pd1[i] = 1000 + 60.0 * i;
		std::cout << "Memory contents;\n";
		for (int i = 0; i < N; ++i)
		{
			std::cout << pd1[i] << " at " << &pd1[i] << "; ";
			std::cout << pd2[i] << " at " << &pd2[i] << std::endl;
		}
		delete[] pd1;
		delete[] pd3;
		return 0;
	}
	Memory addresses:
	heap: 000001AE8B4685E0 static:00007FF72FC9F440
	Memory contents:
	1000 at 000001AE8B4685E0; 1000 at 00007FF72FC9F440
	1020 at 000001AE8B4685E8; 1020 at 00007FF72FC9F448
	1040 at 000001AE8B4685F0; 1040 at 00007FF72FC9F450
	1060 at 000001AE8B4685F8; 1060 at 00007FF72FC9F458
	1080 at 000001AE8B468600; 1080 at 00007FF72FC9F460
	Memory contents:
	1000 at 000001AE8B468570; 1000 at 00007FF72FC9F440
	1040 at 000001AE8B468578; 1040 at 00007FF72FC9F448
	1080 at 000001AE8B468580; 1080 at 00007FF72FC9F450
	1120 at 000001AE8B468588; 1120 at 00007FF72FC9F458
	1160 at 000001AE8B468590; 1160 at 00007FF72FC9F460
	Memory contents;
	1000 at 000001AE8B468490; 1000 at 00007FF72FC9F468
	1060 at 000001AE8B468498; 1060 at 00007FF72FC9F470
	1120 at 000001AE8B4684A0; 1120 at 00007FF72FC9F478
	1180 at 000001AE8B4684A8; 1180 at 00007FF72FC9F480
	1240 at 000001AE8B4684B0; 1240 at 00007FF72FC9F488

定位new运算符将pd2放在buffer数组里面,但是程序会将buffer数组进行强制转换成(void *)。
定位new运算符将不识别哪些内存单元已经被使用过,也不查找未使用的内存块,仅仅根据程序员分配的位置作为起始位置来分配地址
delete只能处理指向常规new运算符分配的堆内存,而不处理定位new运算符,所以通过使用定位new运算符分配的空间不能使用delete处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值