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

  1. 对于相同变量名的变量,CPP会覆盖作用域大的变量,而使用作用域小的变量,如果想在函数体内使用全局的变量可以在变量名前加上::加以区分,比如warm=3会使得局部的warm变量等于3,而::warm=3会使得全局的warm=3 。
  2. 存储描述 持续性 作用域 链接性 声明 举例
    自动变量 自动 代码块 在代码块函数中 int a = 0;
    静态,无链接性变量 静态 代码块 在代码块函数中,使用关键字static static 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
	#include
	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处理。

你可能感兴趣的:(c++,笔记,c++)