------/new关键字
C++动态内存分配通过new关键字进行,其基于类型,delete关键字用于释放
变量申请:Type* pointer = new Type; delete pointer; //堆空间
数组申请:Type* pointer = new Type[N]; delete[] pointer; //[]数组标示符
int* p = new int[10];
for(int i=0; i<10; i++)
{
p[i] = i + 1;
printf("p[%d] = %d\n", i, p[i]);
}
delete[] p;
new关键字与malloc函数区别:
new关键字是C++一部分,malloc是由C库提供的函数
new以具体类型为单位进行内存分配,malloc只能以字节为单位进行内存分配
new在申请单个变量时可进行初始化,malloc不具备内存初始化特性
new关键字的初始化:
int* pi = 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,pf,pc;
------/命名空间
C中只有一个全局作用域,其所有全局标识符共享同一作用域,标识符之间可能发生冲突
C++中提出命名空间概念,将全局作用域分成不同部分,不同命名空间标识符可同名而不会冲突,命名空间可相互嵌套,全局作用域也叫默认命名空间
命名空间定义:namespace name{ /* … */ }
使用某命名空间内所有标示符:using namespace name;
使用某命名空间内某标示符:using name::variable;
使用默认命名空间(无名字的命名空间)内变量:::variable
namespace First
{
int i = 0;
}
namespace Second
{
int i = 1;
namespace Internal
{
struct P
{
int x;
int y;
};
}
}
int a=10;
int main()
{
printf("%d,%d\n",a,::a); //默认命名空间内变量
using namespace First;
printf("i = %d\n", i);
printf("i = %d\n", Second::i);
using Second::Internal::P;
P p = {2, 3};
printf("p.x = %d\n", p.x);
printf("p.y = %d\n", p.y);
return 0;
}
------/强制类型转换
C方式强制类型转换存在的问题:
过于粗暴(任意类型之间都可进行转换,编译器很难判断其正确性)
难于定位(源码中无法快速定位使用强制类型转换的语句)
难检查的bug:运算符优先级、多线程交互、强制类型转换
C++将强制类型转换分为4种类型:static_cast、const_cast、dynamic_cast、reinterpret_cast
用法:xxx_cast< Type >( Expression )
------/
static_cast关键字:
用于基本类型间转换,但不能用于基本类型指针间转换
用于有继承关系类对象之间的转换和类指针之间的转换
int i = 1;
char c = 'c';
int* pi = &i;
char* pc = &c;
c = static_cast<char>(i); //ok
pc = static_cast<char*>(pi); //oops
static_cast在编译期进行转换,无法在运行时检测类型,故转换可能存在风险
------/
const_cast:用于去除变量const属性
const int& j = 1;
int& k = const_cast<int&>(j);
k = 5;
printf("k = %d\n", k); //5
printf("j = %d\n", j); //5
const int x = 2;
int& y = const_cast<int&>(x);
//对常量x取引用,本质取地址,导致为该常量分配内存
y = 8;
printf("x = %d\n", x); //2
printf("y = %d\n", y); //8
printf("&x = %p\n", &x);
printf("&y = %p\n", &y); //地址同
------/
reinterpret_cast:指针类型间、整数和指针类型间强制转换
int i = 0;
char c = 'c';
int* pi = &i;
char* pc = &c;
pc = reinterpret_cast<char*>(pi);
pi = reinterpret_cast<int*>(pc);
PF*p=reinterpret_cast<PF*>(0x123); //必须带括号
reinterpret_cast直接从二进制位进行复制,是一种极其不安全的转换
------/
dynamic_cast:主要用于类层次间转换,还可用于类之间交叉转换,其具有类型检查功能,比static_cast安全
C++动态内存分配通过new关键字进行,其基于类型,delete关键字用于释放
变量申请:Type* pointer = new Type; delete pointer; //堆空间
数组申请:Type* pointer = new Type[N]; delete[] pointer; //[]数组标示符
int* p = new int[10];
for(int i=0; i<10; i++)
{
p[i] = i + 1;
printf("p[%d] = %d\n", i, p[i]);
}
delete[] p;
new关键字与malloc函数区别:
new关键字是C++一部分,malloc是由C库提供的函数
new以具体类型为单位进行内存分配,malloc只能以字节为单位进行内存分配
new在申请单个变量时可进行初始化,malloc不具备内存初始化特性
new关键字的初始化:
int* pi = 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,pf,pc;
------/命名空间
C中只有一个全局作用域,其所有全局标识符共享同一作用域,标识符之间可能发生冲突
C++中提出命名空间概念,将全局作用域分成不同部分,不同命名空间标识符可同名而不会冲突,命名空间可相互嵌套,全局作用域也叫默认命名空间
命名空间定义:namespace name{ /* … */ }
使用某命名空间内所有标示符:using namespace name;
使用某命名空间内某标示符:using name::variable;
使用默认命名空间(无名字的命名空间)内变量:::variable
namespace First
{
int i = 0;
}
namespace Second
{
int i = 1;
namespace Internal
{
struct P
{
int x;
int y;
};
}
}
int a=10;
int main()
{
printf("%d,%d\n",a,::a); //默认命名空间内变量
using namespace First;
printf("i = %d\n", i);
printf("i = %d\n", Second::i);
using Second::Internal::P;
P p = {2, 3};
printf("p.x = %d\n", p.x);
printf("p.y = %d\n", p.y);
return 0;
}
------/强制类型转换
C方式强制类型转换存在的问题:
过于粗暴(任意类型之间都可进行转换,编译器很难判断其正确性)
难于定位(源码中无法快速定位使用强制类型转换的语句)
难检查的bug:运算符优先级、多线程交互、强制类型转换
C++将强制类型转换分为4种类型:static_cast、const_cast、dynamic_cast、reinterpret_cast
用法:xxx_cast< Type >( Expression )
------/
static_cast关键字:
用于基本类型间转换,但不能用于基本类型指针间转换
用于有继承关系类对象之间的转换和类指针之间的转换
int i = 1;
char c = 'c';
int* pi = &i;
char* pc = &c;
c = static_cast<char>(i); //ok
pc = static_cast<char*>(pi); //oops
static_cast在编译期进行转换,无法在运行时检测类型,故转换可能存在风险
------/
const_cast:用于去除变量const属性
const int& j = 1;
int& k = const_cast<int&>(j);
k = 5;
printf("k = %d\n", k); //5
printf("j = %d\n", j); //5
const int x = 2;
int& y = const_cast<int&>(x);
//对常量x取引用,本质取地址,导致为该常量分配内存
y = 8;
printf("x = %d\n", x); //2
printf("y = %d\n", y); //8
printf("&x = %p\n", &x);
printf("&y = %p\n", &y); //地址同
------/
reinterpret_cast:指针类型间、整数和指针类型间强制转换
int i = 0;
char c = 'c';
int* pi = &i;
char* pc = &c;
pc = reinterpret_cast<char*>(pi);
pi = reinterpret_cast<int*>(pc);
PF*p=reinterpret_cast<PF*>(0x123); //必须带括号
reinterpret_cast直接从二进制位进行复制,是一种极其不安全的转换
------/
dynamic_cast:主要用于类层次间转换,还可用于类之间交叉转换,其具有类型检查功能,比static_cast安全