C++学习笔记9 C++新的关键字

来源:互联网 发布:软件试用报告 编辑:程序博客网 时间:2024/06/08 00:16

1:动态内存分配:

C++中通过new关键字进行动态内存申请

C++中的动态内存申请时基于类型进行的

delete用于内存的释放

 

变量申请:

Type* Pointer = new Type;

//

delete Pointer;

 

数组申请:

Type* Pointer = new Type[n];

//

delete [] Pointer;

 

int main(int argc, char** argv) {
 
 int* p = new int;
 *p = 5;
 *p = *p + 10;
 
 printf("p = %p\n",p);
 printf("*p = %d\n",*p);
 
 delete p;
 
 p = new int[10];
 
 for(int i = 0; i < 10; i++)
 {
  p[i] = i;
  printf("p[i] = %d\n",p[i]);
 }
 
 delete []p;
 
 getchar();
 return 0;
}

 

new 关键字与malloc函数的区别:

new关键字是C++的一部分,malloc是C库提供的函数

new以具体类型为单位进行内存分配,malloc只能以字节为单位进行内存分配

new在申请单个变量时可以初始化,malloc不具备初始化的功能

 

new关键字的初始化:

int main(int argc, char** argv) {
 
 int* p = new int(3333);
 float* q = new float(2.2f);
 char * pc = new char('c');
 

 printf("*p = %d\n",*p);
 printf("*q = %f\n",*q);
 printf("*pc = %c\n",*pc);
 delete p;
 
 p = new int[10];
 

 
 getchar();
 return 0;
}

 

2:C++中的命名空间:

在C语言中只有一个全局作用域;

C语言中的所有的全局标识符共享同一个作用域;

标示符之间可能产生冲突;

C++中提出了命名空间的概念:

命名空间将全局作用域分成不同的部分
不同命名空间中的标识符可以同名而不会发生冲突
命名空间可以相互嵌套
全局作用域也叫默认命名空间

namespace First
 {
  int i= 0;
 } 
 
namespace Second
 {
  int i= 9;
 }
 

int main(int argc, char** argv) {
 
 
 getchar();
 return 0;
}

 

C++命名空间的使用:
使用整个命名空间:using namespace name;
使用命名空间中的变量:using name::variable;
使用默认命名空间中的变量:::variable

默认情况下可以直接使用默认命名空间中的所有标示符

namespace First
 {
  int i= 0;
 }
 
namespace Second
 {
  int i= 9;
  
  namespace Three
  {
   struct p
   {
    int x;
    int y;
   };
  }
 }

int main(int argc, char** argv) {
 
 using namespace First;
 using Second::Three::p;
 
 printf("i = %d\n",i);
 printf("i = %d\n", Second::i);
 
 p P = {2,3};
 printf("p->x = %d\n", P.x);
 printf("p->x = %d\n", P.y);
 
 
 getchar();
 return 0;
}

3:强制类型转换:

C方式的强制类型转换:

(Type)(Expression)与 Type(Expression)

typedef void(PF)(int);struct Point{ int x;int y;};int main(int argc, char** argv) {int v = 0x12345;PF* pf = (PF*)v;char c = (char)(v); pf(v);  Point * p = (Point*)v;  printf("p->x = %d\n",p->x); printf("p->y = %d\n",p->y); getchar();return 0;}


上面的代码可以编译通过在C编译器中,但是运行报错。C语言方式的强制类型转换很危险

C方式强制类型转换存在的问题
过于粗暴
任意类型之间都可以进行转换,编译器很难判断其正确性
难于定位
在源码中无法快速定位所有使用强制类型转换的语句
    在程序设计理论中强制类型转换是不被推荐的,与goto语句一样,应该尽量避免。

 

C++中有4中强制类型转换:

static_cast,const_cast,dynamic_cast,reinterpret_cast;

<1>static_cast 强制类型转换:

用于基本类型之间强制转换,但不能用于基本类型指针之间的转换

用于有继承关系的类对象之间的转换与类指针之间的转换

int main(int argc, char** argv) {int  i = 0;char c = 'c';int * pi = &i;char * pc = &c;  //static_cast 用于一般类型之间的转换但是不能用于一般类型指针之间的转换  c = static_cast<char>(i);//pc = static_cast<char*>(pi);  getchar();return 0;}


static_cast是编译期进行转换的,无法在运行时检测类型,
所以类类型之间的转换可能存在风险。

<2> const_cast强制类型之间的转换

--用于去除变量的cosnt属性

int main(int argc, char** argv) {//去掉const属性 const int& j = 1; //const 引用初始化  j是一个只读变量 int& k = const_cast<int &>(j);const int x = 2; //x是一个常量 int& y = const_cast<int&>(x);k = 5;printf("k = %d\n",k);printf( "j = %d\n",j); y = 7;printf("x = %d\n",x); //直接从符号表取值 printf("y = %d\n",y);printf("&x= %p\n",&x);printf("&y = %p\n",&y); getchar();return 0;}


<3> reinterpret_cast强制类型转换

用于指针类型间的强制转换
―用于整数和指针类型间的强制转换

typedef void(PF)(int); int main(int argc, char** argv) {int i = 0;char c = 'c';int * pi = reinterpret_cast<int *>(&c);char* pc = reinterpret_cast<char *>(&i);//c = reinterpret_cast<char>(i);getchar();return 0;}


reinterpret_cast直接从二进制位进行复制,是一种极其不安全的转换。

 

<4>:dynamic_cast类型之间的转换

主要用于类层次间的转换,还可以用于类之间的交叉转换
―dynamic_cast具有类型检查的功能,比static_cast更安全

 

 总结:

C++中内置了动态内存分配的专用关键字
C++中的动态内存分配是基于类型进行的
C++中命名空间概念用于解决名称冲突问题
C++细化了C语言中强制类型转换的方式

 


0 0
原创粉丝点击