C++基础学习笔记----第五课(动态内存分配、命名空间、强制类型转换)(二)

2014-11-24 02:59:09 · 作者: · 浏览: 5
的嵌套命名空间(第一个first嵌套第二first),这个时候实际上我们把两个first都打开了,所以实际上我们可以使用两个命名空间了,上述程序最后的打印结果是0,也就是打印第一层命名空间中的i。

#include 
  
   

namespace first
{
	int i = 0;
	namespace first
	{
		int i = 5;
	}
}

int main()
{
	using namespace first::first;

	
	printf ("%d",i);
}
  
上述程序的打印结果是5,我们在 程序开始运行的时候就已经确定直接打开第二层first的命名空间,所以这个时候打印的i是第二层命名空间对应的i.
2.如果 不是嵌套关系的两个命名空间同名,并 且命名空间中的变量也没有出现重名的现象,那么程序可以进行正常运行。例程如下:

#include 
  
   

namespace first
{
	int i = 0;
}

namespace first
{
	int b = 8;
}

int main()
{
	using namespace first;

	printf ("%d",i);
}
  
3.如果被嵌套的命名空间的名字和其他的并排命名空间的名字重名,要注意打开命名空间的顺序和到底是哪个打开了,这个时候程序可以运行。

4.一个命名空间下可以嵌套多个命名空间,这多个命名空间可以重名,不过重名的时候空间中的标示符不允许相同,否则程序运行报错。例程如下:

#include 
  
   

namespace first
{
	int i = 0;
	namespace first
	{
		int i = 0;
	}
	namespace first
	{
		int b = 0;
	}
}

int main()
{
	using namespace first;

	printf ("%d",i);
}

  

C++中的强制类型转换

C语言的强制类型转换

C语言的强制类型转换主要有两种形式, (Type)(Expression)or Type(Expressiong),常用的是第一种形式的强制类型转换,第二种不是很常用。

C语言抢孩子类型转换的弊端:①过于粗暴,任意类型之间都可以进行转换,编译器很难判断是否正确。②难于定位,在源码中无法快速定位所有使用强制类型转换的语句。

注意:在程序设计理论中强制类型转换不被推荐,与goto语句一样,应该进行避免,因为在程序设计过程中,定义变量就应该清楚变量的使用环境,直接定义成有效的类型,避免强制类型转换。现代编程中的三个BUG的主要来源:三个BUG的源泉:①运算符优先级(位运算,逻辑运算,数学运算混合使用)②多线程编程(线程之间的转换)③强制类型转换

C++中的强制类型转换方法

1.static_cast强制类型转换

这种强制类型转换的方式主要用于基本类型之间的转换,不能够用于基本类型之间的指针转换。用于有继承关系类对象之间的转换和类指针之间的转换。

基本例程如下:

#include 
  
   

int main()
{
	int a = 1;
	char b = 'a';
	int *c = &a;
	char *d = &b;
	
	b = static_cast
   
    (a); printf ("%c", b); return 0; }
   
  
错误的例程(不能够用于基本类型指针之间的转换)

#include 
  
   

int main()
{
	int a = 1;
	char b = 'a';
	int *c = &a;
	char *d = &b;
	
	c = static_cast
   
    (d); return 0; } 
   
  
程序无法编译通过。

2.const_cast强制类型转换

这种方式主要用于去除变量的const属性。
这种方式去除变量的const属性主要有两种形式,①const int* p②const int& p例程如下:

#include 
  
   

int main()
{
	const int& a = 1; //const与引用结合让一个变量变为了一个只读变量
	int& b = const_cast
   
    (a); //这里通过const_cast来进行强制类型转换,这个时候a就由一个 //只读变量降级为一个普通变量被b引用。 b = 8; //a = 9; 这条语句经过编译会报错,因为a虽然经过了强制类型转换,但是a仍然是一个只读变量,不够被赋值 printf ("%d\n",b); printf ("%d\n",a); }
   
  
#include 
  
   

int main()
{
	const int c = 2; //这里的const在C++中起到的作用是c成为一个常量,在程序开始编译的时候就已经进入符号表
	//将常量的const属性去掉之后,由于对c取了引用,也就是对一个常量取了地址,所以编译器会分配内存,
	//这个时候d就是c这个常量的内存地址的别名。这个时候d完全可以当做一个普通变量来使用了。
	int& d = const_cast
   
    (c); d = 9; printf ("%d\n",c); printf ("%d\n",d); }
   
  
程序打印结果是2,9

#include 
  
   

int main()
{
	int i = 5;
	const int* a = &i; //根据const的属性,此时的*a整体的值是不能够改变的
	int* b = const_cast
   
    (a); //这里去掉了*a的const属性,赋给*b *b = 9; //这里改变a的const属性已经被去掉,所以改变b指向的内存值,a的值也会发生改变。 printf ("%p\n", a); printf ("%p\n", b); printf ("*a = %d", *a); printf ("*b = %d", *b); }
   
  
程序打印结果如下图所示:

\

除了上面两种情况,还有一种情况是int const *p ,这个应该很熟悉吧,这是引用嘛。例程如下:

#include 
  
   

int main()
{
	int i = 5;
	int* const a = &i; //根据const的属性,此时的a的值是不能够改变的
	int* b = const_cast
   
    (a); //这里去掉了*a的const属性,赋给*b int cc = 8; a = &cc; //b = &cc; printf ("%p\n", a); printf ("%p\n", b); printf ("*a = %d\n", *a); printf ("*b = %d\n", *b); } 
   
  
这里程序编译失败,因为我们无法去除掉int* const a的const属性,这也是引用的实质,一旦指向就无法改变了。
3.reinterpret_cast强制类型转换

主要用于指针间的强制类型转换,用于整数和指针间的强制类型转换。这里的指针类型的强制类型转换,都是没有const属性去除的,如果有const属性去除的要求优先考虑去除const属性的要求。

#include 
  
   

int main()
{
    int i = 0;
    char c = 'c';
    int* pi = &i;
    char* pc = &c;
    
    pc = reinterpret_cast
   
    (pi); pi = reinterpret_cast
    
     (pc); c = reinterpret_cast
     
      (i); // Oops! printf("Press any key to continue..."); getchar()