标签:方便 cas malloc xxx 初始化 oop body erp 左值
(1)C++通过 new 关键字进行动态内存申请,是以类型为单位来申请空间大小的
(2)delete 关键字用于内存释放
▲注意释放数组时要加[],否则只释放这个数组中的第 1 个元素。
C++中的动态内存分配
#include <stdio.h> int main() { int* p = new int; *p = 5; *p = *p + 10; printf("p = %p\n", p); //p 保存堆上开辟空间的地址 printf("*p = %d\n", *p);//15 delete p; p = new int[10];//申请 10 个 int 型空间 for(int i=0;i<10; i++) { p[i] = i + 1; printf("p[%d] = %d\n", i, p[i]); } delete[] p; //注意:释放数组时[]不能漏掉 return 0; }
(1)对比 new 和 malloc
new |
malloc |
|
性质 |
是个关键字,属C++的一部分 |
是由C库提供的函数 |
申请单位 |
以具体类型为单位 |
以字节为单位 |
内存初始化 |
申请单个类型变量时可进行初始化 |
不具备内存初始化的特性 |
(2)new 关键字的初始化
int* pi = new int(1); float* pf = new float(2.0f); char* pc = new char(‘c‘);
初始化动态内存
#include <stdio.h> int main() { int* pi = new int(1); //开辟1个int型空间,并初始化为1 //int* pa = new int[1];//注意,这时申请一个数组,与前一行含义不同 float* pf = new float(2.0f); char* pc = new char(‘c‘); printf("*pi = %d\n", *pi); //1 printf("*pf = %f\n", *pf); //2.000000 printf("*pc = %c\n", *pc); //c delete pi; delete pf; delete pc; return 0; }
C++中命名空间概念用于解决名称冲突问题
(1)在 C 语言中只有一个全局作用域
①C 语言中所有的全局标识符共享同一个作用域
②标识符之间可能发生冲突
(2)C++中提出了命名空间的概念
①命名空间将全局作用域分成不同的部分
②不同命名空间中的标识符可以同名而不会发生冲突
③命名空间可以相互嵌套
④全局作用域也叫默认命名空间
(3)C++命名空间的定义:namespace Name {}
①使用整个命名空间:using namespace name;
②使用命名空间中的变量:using name::variable;
③使用默认命名空间中的变量: ::variable
命名空间的使用
#include <stdio.h> namespace First { int i = 0; } namespace Second { int i = 1; //命名空间的嵌套 namespace Internal { struct P { int x; int y; }; } } int main() { using namespace First;//使用First整个命名空间 using Second::Internal::P;//使用命名空内部的P结构体 printf("Fisrt::i = %d\n", i); //0。可以直接写i,因为使用了First整个命名空间 printf("Second::i = %d\n", Second::i);//1。须带命名空间的名字 P p = {2, 3}; printf("p.x = %d\n", p.x);//2 printf("p.y = %d\n", p.y);//3 return 0; }
(1)转换形式
①(Type)(Expression)
②Type(Expression) //老式的
#include <stdio.h> typedef void PF(int); struct Point { int x; int y; }; int main() { int v = 0x12345; PF* pf = (PF*)v; char c = char(v);//老式写法,很像函数调用 Point* p = (Point*)v; pf(5); printf("p->x = %d\n", p->x); printf("p->y = %d\n", p->y); return 0; }
(2)强制类型转换存在的问题
①过于粗暴:任意类型之间都可以进行转换,编译器很难判断其正确性
②难于定位:在源码中无法快速定位所有使用强制类型转换的语句
(1)用法:xxx_cast(Type)(Expression)
(2)4 种类型
类型 |
适用范围 |
举例 |
备注 |
static_cast |
①基本类型之间 ②不能用于基本类型的指针之间 ③类与子类对象之间的转换或类指针间转换 |
int i = 0; char c = ‘A‘;
int* pi = &i; char* pc = &c;
c = static_cast<char>(i); //ok
//不能用于基本类型的指针间转换 pc = static_cast<char*>(pi);//oops |
|
const_cast |
目标类型(即尖括号内的类型)必须是指针或引用 |
//i有内存,因别名,每次从内存读取i const int& i = 1;//i为引用 int& a = const_cast<int&>(i);
const int j = 1; //为j分配内存,但不会去用它,从符号表中取j int& b = const_cast<int&>(j);
a = 5; //i==5;a==5; b = 3; //j==1,b==3; |
用于去除变量的const属性 |
reinterpret_cast |
①用于指针类型间 ②用于整数和指针类型之间 |
typedef void PF(int);
int i = 0; char c = ‘c‘;
int* pi = reinterpret_cast<int*>(&c); char*pc = reinterpret_cast<char*>(&i);
PF*pf= reinterpret_cast<PF*>(0x12345678);
//以下错,要用static_cast c = reinterpret_cast<char>(i); |
reinterpret_cast直接从二进制位进行复制,是一种极其不安全的转换。 |
dynamic_cast |
①用于有继承关系的类指针间。②用于有交叉关系的类指针之间
|
详见后面章节的分析 |
①dynamic_cast具有类型检查的功能 ②需要虚函数的支持 |
#include <stdio.h> void static_cast_demo() { int i = 0x12345; char c = ‘c‘; int* pi = &i; char* pc = &c; c = static_cast<char>(i);//基本类型 //基本类型的指针间,非法 //pc = static_cast<char*>(pi); } void const_cast_demo() { //用常量初始化引用,要分配内存。故j为变量,因加const而成只读变量 const int& j = 1;//j为引用--》只读变量,说明j不能做为左值而己 int& k = const_cast<int&>(j); //转为普通引用,k就是j的别名 k = 5; printf("k = %d\n", k); //5 printf("j = %d\n", j); //5 const int x = 2; //x为常量 int& y = const_cast<int&>(x);//此时,会为x分配内存 //int z = const_cast<int>(x); //oops,目标类型只能是引用或指针 y = 3; printf("x = %d\n", x); //2 printf("y = %d\n", y); //3 printf("&x = %d\n", &x); printf("&y = %d\n", &y); //x与y的内存地址是相同的 } void reinterpret_cast_demo() { int i = 0; char c = ‘c‘; int* pi = &i; char* pc = &c; pc = reinterpret_cast<char*>(pi); //ok,指针间 pi = reinterpret_cast<int*>(pc); //ok,指针间 pi = reinterpret_cast<int*>(i); //ok,整数与指针间 //c = reinterpret_cast<char>(i); //oops,基本类型间转换,要用static_cast } void dynamic_cast_demo() { int i = 0; int* pi = &i; char* pc = dynamic_cast<char*>(pi);//oops,目标类型应为类的指针或引用 } int main() { static_cast_demo(); const_cast_demo(); reinterpret_cast_demo(); dynamic_cast_demo(); return 0; }
新式类型转换以 C++关键字的方式出现
①编译器能够帮助检查潜在的问题
②非常方便的在代码中定位
③支持动态类型识别(dynamic_cast)
标签:方便 cas malloc xxx 初始化 oop body erp 左值
原文地址:http://www.cnblogs.com/CoderTian/p/7753053.html