1.类型转换
(1)statuc_cast
A:普通类型数值之间的转换,不能进行指针之间的转换;
double d = 1.2;
//int a1 = (int)d;//强制类型转换
//printf("a1 = %d\n",a1);
int a1 = static_cast<int>(d);
printf("a1 = %d\n",a1);
B:有隐式声明的地方都可以调用static_cast进行转换;
也就是基类指针指向派生类对象
Person *p = static_cast<Person *>(&s);
(2)reinterpret_cast
A:用于指针类型之间的转换
double *pd = &d;
//int *pa = (int *)(pd);
//printf("*pa = %d\n",*pa);
int* pa = reinterpret_cast<int *>(pd);
printf("*pa = %d\n",*pa);
B:将变量转换为指针
int a2 = 10;
printf("&a2 = %p\n",&a2);
int a3;
scanf("%p",&a3);
int *pa2 = reinterpret_cast<int *>(a3);
*pa2 = 200;
printf("a2 = %d\n",a2);//a2 = 200
(3)dynamic_cast
将派生类对象指针转换成基类对象指针;
如果 类型匹配,转换成功,返回指向派生类对象的指针;
如果 类型不匹配,则转换失败,返回NULL指针。
void func(A *pa)
{
pa->sleep();//多态
//Dog *pd = (Dog *)pa;//强制类型转换
//pd->lookHome();
Dog *pd = dynamic_cast<Dog *>(pa);
if(pd != NULL)
pd->lookHome();
}
(4)const_cast
将一个const常量转换为一个非const变量;
void func(const char *s)
{
char *ps = const_cast<char *>(s);
ps[0] = 'w';
//s[0] = 'h';//不成立,将s转一个非换成为const变量ps,ps是
一个变量,是可以改变值的,s始终是一个常量,转换前和转换后类型不变。
}
char str[] = "hello world";
//char *str = "hello world";//字符串常量,常量的值是不能改变的
2.异常的概念:非常有利于做错误处理。
思想:将错误的发生地点和错误的处理地点相分离。
(1)步骤:
A:抛异常用throw
B:捕捉异常用try{}catch(){}
void divid(int x,int y)
{
if(y == 0)
{
throw x;
printf("抛出一个异常\n");
}
printf("%d / %d = %d\n",x,y,x/y);
}
try
{
divid(10,0);
}
catch(int e)//异常的匹配类型
{
printf("捕捉到一个异常 %d\n",x);
}
catch(double e)
{}
catch(...)
{}
(2)注意:
A:异常是要匹配类型的,异常是自己抛的,系统不会抛异常
B:异常是跨函数的
C:异常被捕捉以后,可以继续抛,也可以不抛
D:异常变量的捕捉要进行严格的类型匹配,不允许隐式的类型匹配
3.栈解旋和异常接口
栈解旋:栈的自动析构
A *pa = new A(10);//堆上空间,必须自己释放
divid(10,0);
异常的接口声明:
void test()throw(int,char,double)...//该函数只能抛
出int,char,double这三种类型的异常
void test1()throw()...//不允许抛出异常
(1)statuc_cast
A:普通类型数值之间的转换,不能进行指针之间的转换;
double d = 1.2;
//int a1 = (int)d;//强制类型转换
//printf("a1 = %d\n",a1);
int a1 = static_cast<int>(d);
printf("a1 = %d\n",a1);
B:有隐式声明的地方都可以调用static_cast进行转换;
也就是基类指针指向派生类对象
Person *p = static_cast<Person *>(&s);
(2)reinterpret_cast
A:用于指针类型之间的转换
double *pd = &d;
//int *pa = (int *)(pd);
//printf("*pa = %d\n",*pa);
int* pa = reinterpret_cast<int *>(pd);
printf("*pa = %d\n",*pa);
B:将变量转换为指针
int a2 = 10;
printf("&a2 = %p\n",&a2);
int a3;
scanf("%p",&a3);
int *pa2 = reinterpret_cast<int *>(a3);
*pa2 = 200;
printf("a2 = %d\n",a2);//a2 = 200
(3)dynamic_cast
将派生类对象指针转换成基类对象指针;
如果 类型匹配,转换成功,返回指向派生类对象的指针;
如果 类型不匹配,则转换失败,返回NULL指针。
void func(A *pa)
{
pa->sleep();//多态
//Dog *pd = (Dog *)pa;//强制类型转换
//pd->lookHome();
Dog *pd = dynamic_cast<Dog *>(pa);
if(pd != NULL)
pd->lookHome();
}
(4)const_cast
将一个const常量转换为一个非const变量;
void func(const char *s)
{
char *ps = const_cast<char *>(s);
ps[0] = 'w';
//s[0] = 'h';//不成立,将s转一个非换成为const变量ps,ps是
一个变量,是可以改变值的,s始终是一个常量,转换前和转换后类型不变。
}
char str[] = "hello world";
//char *str = "hello world";//字符串常量,常量的值是不能改变的
2.异常的概念:非常有利于做错误处理。
思想:将错误的发生地点和错误的处理地点相分离。
(1)步骤:
A:抛异常用throw
B:捕捉异常用try{}catch(){}
void divid(int x,int y)
{
if(y == 0)
{
throw x;
printf("抛出一个异常\n");
}
printf("%d / %d = %d\n",x,y,x/y);
}
try
{
divid(10,0);
}
catch(int e)//异常的匹配类型
{
printf("捕捉到一个异常 %d\n",x);
}
catch(double e)
{}
catch(...)
{}
(2)注意:
A:异常是要匹配类型的,异常是自己抛的,系统不会抛异常
B:异常是跨函数的
C:异常被捕捉以后,可以继续抛,也可以不抛
D:异常变量的捕捉要进行严格的类型匹配,不允许隐式的类型匹配
3.栈解旋和异常接口
栈解旋:栈的自动析构
A *pa = new A(10);//堆上空间,必须自己释放
divid(10,0);
异常的接口声明:
void test()throw(int,char,double)...//该函数只能抛
出int,char,double这三种类型的异常
void test1()throw()...//不允许抛出异常