一 .动态内存分配
- C++中使用new关键字进行动态内存分配。
- C++中的动态内存分配是基于类型的
- delete关键字用于内存的释放。
变量申请:
Type* p = new Type;
delete p;
数组申请:
Type* p = new Type[N];
delete [] p;
#include <stdio.h>
int main()
{
int* p = new int;
*p = 5;
*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[%d] = %d\n",i,p[i]);
}
delete [] p;
return 0;
}
new与关键字malloc的区别
- new关键字是C++的一部分,malloc是C库提供的函数。
- new是以具体类型进行内存分配的,而malloc只能以几节为单位进行内存分配。
- new在申请单个内存是可以进行初始化,malloc不具备内存初始化的特征。
new关键字的初始化:
#include <stdio.h>
int main()
{
int* pi = new int(1);
float* pf = new float(0.123f);
char* pc = new char('c');
printf("*pi = %d\n",*pi);
printf("*pt = %f\n",*pf);
printf("*pc = %c\n",*pc);
delete pi;
delete pf;
delete pc;
return 0;
}
二 . C++中的命名空间
说明:(1)命名空间将全局作用域分成不同的部分。
(2)不同命名空间的相同的标示符也不会发生冲突。
命名空间的定义:
namespaces name{ .......... }
C++中命名空间的使用:
使用整个命名空间:using namespace name;
使用命名空间中的变量:using name::variable;
使用默认命名空间中的变量: ::variable;
#include <stdio.h>
namespace First
{
int i =0;
}
namespace Second
{
int i = 1;
namespace Inster
{
struct p
{
int x;
int y;
};
}
}
int main()
{
using namespace First;
using Second::Inster::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.y= %d\n",_p.y);
return 0;
}
三 . 强制类型转换
(Type) (Expression) or 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);
pf(v);
Point* po =(Point*)v;
printf("(%d,%d)\n",po->x,po->y);
return 0;
}
虽然编译过程中没有错误,但是运行过程中出现错误。所以也是程序容易出现问题的地方。
C++将强制类型转换分成4中不同的类型:
(1) static_cast
- 用于基本类型间的转换,但不能用于基本类型指针间的转换。
- 用于有继承关系类对象之间的转换和类指针之间的转换
#include <stdio.h>
int main()
{
int i = 3;
char c = 'f';
int *p = &i;
char *pc = &c;
c = static_cast<char>(i);
//pc = static_cast<char*>pc;//错误
printf("%c",c);
return 0;
}
(2)const_cast强制类型转换
---------------------------用于除去变量const属性。
#include <stdio.h>
int main()
{
const int& j = 1; //常引用变量
int& k = const_cast<int&>(j); //除去const属性
const int x = 2; //普通常变量
int& y = const_cast<int&>(x);
k = 5; ///改变k的值
printf("j=%d\n",j);
printf("k=%d\n",k);
y = 3;
printf("x=%d\n",x);
printf("y=%d\n",y);
printf("&x=%p\n",&x);
printf("&y=%p\n",&y);
return 0;
}
************************************************************
const int x = 2; 它的引用也无法改变x的值,始终为一个常量,说明C++对const进行了优化。其实这个可以用符号表来解释,就是编译器把x=2存入了符号表。
(3)reinterpret_cast
- 用于指针类型间的强制类型转换;
- 用于整数和指针类型间强制类型转换
#include <stdio.h>
typedef void (PF)(int);
int main()
{
int i = 0;
char c = 'c';
int* pi = reinterpret_cast<int*>(&c);//字符转换成整形指针
char* pc = reinterpret_cast<char*>(&i);//整形指针转换成字符指针
PF* pf= reinterpret_cast<PF*>(0x12345678);//
//c = reinterpret_cast<char>i; //错误
return 0;
}
reinterpret_cast 直接从二级制位进行复制,是一种及其不安全的转换。
(4)dynamic_cast 强制类型转换
----------------主要用于类层次间的转换,还用于类交互间的转换。
---------------dynamic_cast 具有类型检查功能,比reinterpret_cast 更安全。