类型转换
在 c语言 中,类型转换时很简单的,大致分为两种:
1.隐式转换
char c = 'A';
int a = c; // a = 65
2.强制转换
double d = 1.2;
int a = (int) d; // 丢失小数部分
这会导致两个问题的出现:
1)任何类型之间都可以转换,编译器很难判断正确性;
2)在源码中无法快速定位所有使用强制类型转换的语句;
因此,在程序设计理论中,强制类型转换不被推荐,与 goto 语句一样,应当 尽量避免。
C++ 提供了四种类型转换:
1. static_cast;
2. reinterpret_cast;
3. dynamic_cast;
4. const_cast
static_cast
普通数据类型转换,父子类指针的转换,在编译时进行,无法动态识别类型,不能用于基本类型指针的转换。
#include <iostream>
using namespace std;
class Animal
{
public:
Animal()
{
}
virtual void sleep()
{
printf("动物在睡觉\n");
}
private:
int age;
char *name;
};
class Cat :public Animal
{
public:
Cat()
{
}
void sleep()
{
printf("猫 趴着睡觉\n");
}
};
int main()
{
int a = 2;
double d = 1.2;
char c = 'A';
a = static_cast<int>(c);
cout << "a = " << a << endl;
d = static_cast<double>(a);
cout << "d = " << d << endl;
Animal *p = new Animal;
Cat *pc = new Cat;
// static_cast也可以实现父子类之间的转换,两个不相干的类,无法进行转换
p = pc;
p = static_cast<Animal *>(pc);
return 0;
}
reinterpret_cast
用于指针类型的强制类型转换,用于整数和指针类型之间的强制类型转化(并不安全,不推荐使用)
#include <iostream>
using namespace std;
int main()
{
int a = 5;
int *pa = reinterpret_cast<int *>(&a); // 值的复制
cout << "*pa = " << *pa << endl; // *pa = 5
int tmp; // 将数值转化为指针
scanf_s("%x", &tmp);
pa = reinterpret_cast<int *>(tmp);
*pa = 10;
cout << "a = " << a << endl; // a = 10
return 0;
}
dynamic_cast
实现动态转换,如果转换成功,返回指向该类的指针,否则 返回NULL;
#include <iostream>
using namespace std;
class Animal
{
public:
Animal()
{
}
virtual void sleep()
{
printf("动物在睡觉\n");
}
private:
int age;
char *name;
};
class Cat :public Animal
{
public:
Cat()
{
}
void sleep()
{
printf("猫 趴着睡觉\n");
}
void CatchM()
{
printf("猫 捉老鼠\n");
}
};
class Fish :public Animal
{
public:
Fish()
{
}
void sleep()
{
printf("鱼 睁着眼睡\n");
}
void Bubble()
{
printf("鱼 吐泡泡\n");
}
};
void func1(Animal *p)
{
p->sleep();
Cat *pa = dynamic_cast<Cat *>(p); //转换成 Cat 类型的指针
if (pa != NULL)
{
pa->CatchM();
}
Fish *pf = dynamic_cast<Fish *>(p); //转换成 Fish 类型的指针
if (pf != NULL)
{
pf->Bubble();
}
}
int main()
{
Animal *p = new Animal;
Cat *pc = new Cat;
Fish *pf = new Fish;
func1(p);
func1(pc);
func1(pf);
return 0;
}
const_cast
将 const 常量 转换为 为一个非 const 常量
转换:将一个 变量 按某种方式 赋给 另一个变量,原来变量的属性不变;
#include <iostream>
using namespace std;
void func2(const char* ptr)
{
char *str = const_cast<char *>(ptr);
str[0] = 'w';
ptr = "shanghai";
cout << str << endl;
cout << ptr << endl;
}
int main()
{
//char *ptr = "hello world"; // 常量
char ptr[] = "hello world"; // 使用数组时,在栈上开辟的空间来存放“hello world”,因此,可以修改
func2(ptr);
char* str[] = { "hello", "world" }; // 本质还是常量,常量放在代码段上,无法修改
//func2(str[0]);
return 0;
}
异常
1.异常是一种程序控制机制,与函数机制独立和互补
函数是一种以栈结构展开的上下函数衔接的程序控制系统,异常是另一种控制结构,它依附于栈结构,却可以同时设置多个异常类型作为网捕条件,从而以类型匹配在栈机制中跳跃回馈.
2.异常设计目的
栈机制是一种高度节律性控制机制,面向对象编程却要求对象之间有方向、有目的的控制传动,从一开始,异常就是冲着改变程序控制结构,以适应面向对象程序更有效地工作这个主题,而不是仅为了进行错误处理。
语法
// 捕获并处理异常的程序段
try
{
}
catch(异常类型声明)
{
复合语句
}
catch(异常类型声明 (形参))
{
复合语句
}
catch(...) // 表示其他异常
{
复合语句
}
// 抛掷异常的程序段
void func()
{
throw 表达式;
}