c++类型转换
知识点1 静态类型转换(static_cast)
用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换
进行上行转换:用父类指针、引用指向子类空间(安全)
进行下行转换:用子类指针、引用指向父类空间(不安全)
#include <iostream>
using namespace std;
class Animal{
public:
virtual void showData(){
cout << "父类函数" << endl;
}
};
class Cat: public Animal{
public:
void showData(){
cout << "子类函数" << endl;
}
};
class Other{};
void test01(){
//static_cast 作用于 基本类型
char ch = 'a';
double d = static_cast<double>(ch);
cout<<"d = "<<d<<endl;
//static_cast 作用于 自定义数据类型(结构体 类)
//关系的类之间
//上行转换 安全
Animal *p1 = static_cast<Animal*>(new Cat());
p1->showData();
//下行转换 不全 容易越界
Cat *p2 = static_cast<Cat*>(new Animal);
p2->showData();
// static_cast 不能作用域 不相关的类之间转换
//Animal *p3 = static_cast<Animal *>(new Other);//err
}
int main(int argc, char *argv[])
{
test01();
return 0;
}
运行结果:
知识点2【动态转换dynamaic_cast】
#include <iostream>
using namespace std;
class Animal{
};
class Cat: public Animal{
public:
void showData(){
cout << "子类函数" << endl;
}
};
class Other{};
void test02(){
//static_cast 不支持基本类型
char ch = 'a';
//double d = dynamic_cast<double>(ch);//err
//dynamic_cast 作用于 自定义数据类型(结构体 类)
//关系的类之间
//上行转换 安全
Animal *p1 = dynamic_cast<Animal*>(new Cat());
//dynamic_cast 下行转换 不全 容易越界
//Cat *p2 = dynamic_cast<Cat*>(new Animal());//dynamic_cast不支持 不安全 的转换
// dynamic_cast 不能作用域 不相关的类之间转换
//Animal *p3 = static_cast<Animal *>(new Other);//err
}
int main(int argc, char *argv[])
{
test02();
return 0;
}
知识点3【常量转换const_cast】
//常量转换const_cast
void test03(){
const int *p1 = new int(10);
int *p2 = const_cast<int*>(p1);
int *p3 = new int(20);
const int *p4 = const_cast<const int *>(p3);
//const_cast不支持非指针或引用的转换
const int a = 100;
//int b = const_cast<int>(a);//err
int data = 100;
//普通引用转换成常量引用
int &data1 = data;
const int &data2 = const_cast<const int &>(data1);
}
知识点4【重新解释转换reinterpret_cast】
#include <iostream>
using namespace std;
class Animal{
public:
virtual void showData(){
cout << "父类函数" << endl;
}
};
class Cat: public Animal{
public:
void showData(){
cout << "子类函数" << endl;
}
};
class Other{};
void test04(){
//reinterpret_cast 不支持基本数据类型
char ch='a';
//double d = reinterpret_cast<double>(ch);//err
//reinterpret_cast 支持 不相关的类型间转换
Animal *p1 = reinterpret_cast<Animal *>(new Other);
//上行转换
Animal *p2 = reinterpret_cast<Animal *>(new Cat());
//下行转换
Dog *p3 = reinterpret_cast<Cat *>(new Animal());
}
c++异常
知识点1【异常的概述】
常见的异常:除0溢出,数组下标越界,所要读取的文件不存在,空指针,内存不足等等。
c++的异常一旦抛出 如果不捕获 该异常 程序直接退出。
1、C语言通过返回值 来判断 第一:容易忽略 第二:容易和正常的结果混淆
int myDiv(int a, int b){
if(b == 0){
return -1;
}
return a/b;
}
int main(int argc, char *argv[])
{
int ret = myDiv(10,-10);
if(ret == -1){
cout << "程序异常" << endl;
}else{
cout << "程序正常" << endl;
}
return 0;
}
运行结果:
2、c++抛出异常 并捕获
抛出异常:throw
捕获异常:try…catch
#include <iostream>
#include<string>
using namespace std;
int myDiv(int a,int b)
{
if(b == 0)
return -1;//-1表示失败
return a/b;
}
int myDiv01(int a,int b)
{
if(b==0)
throw 0;//抛出异常
return a/b;
}
void test02()
{
try{
int ret = myDiv01(10,0);
cout<<"ret = "<<ret<<endl;
}
#if 1
catch(int e)//只捕获 抛出是int类型的异常
{
cout<<"捕获到int类型异常 e = "<<e<<endl;
}
#endif
catch(float e)//只捕获 抛出是float类型的异常
{
cout<<"捕获到float类型异常 e = "<<e<<endl;
}
catch(char e)//只捕获 抛出是char类型的异常
{
cout<<"捕获到char类型异常 e = "<<e<<endl;
}
#if 0
catch(...)
{
cout<<"捕获到其他异常"<<endl;
}
#endif
cout<<"程序做其他事情"<<endl;
}
运行结果:
知识点2【栈解旋(unwinding)】
异常被抛出后,从进入try块起,到异常被抛出前,这期间在线上构造所有对象,都会被自动析构。析构的顺序于构造的顺序相反,这一过程称为栈的解旋(unwinding)。
#include <iostream>
#include<string>
using namespace std;
class Person{
private:
string name;
public:
Person(string name)
{
this->name = name;
cout<<"Person "<<name<<"构造函数"<<endl;
}
~Person()
{
cout<<"Person "<<name<<"析构函数"<<endl;
}
};
void test03()
{
try{
Person ob1("00_德玛");
Person ob2("01_小炮");
Person ob3("02_小法");
Person ob4("03_提莫");
throw 10;
}
catch(int)
{
cout<<"捕获到int异常"<<endl;
}
cout<<"其他工作"<<endl;
}
运行结果:
知识点3【异常接口声明】
#include <iostream>
#include<string>
using namespace std;
void testFunc01()
{
//函数内部可以抛出任何异常
//throw 10;
//throw 4.3f;
//throw 'a';
//throw "hehe";
string ob="heihie";
throw ob;
}
//只能抛出int char 异常
void testFunc02() throw(int,char)
{
throw 3.14f;
}
//函数 不抛出任何异常
void testFunc03()throw()
{
throw 10;//外部捕获 不到
}
void test04()
{
try{
testFunc03();
}
catch(int e)//只捕获 抛出是int类型的异常
{
cout<<"捕获到int类型异常 e = "<<e<<endl;
}
catch(float e)//只捕获 抛出是float类型的异常
{
cout<<"捕获到float类型异常 e = "<<e<<endl;
}
catch(char e)//只捕获 抛出是char类型的异常
{
cout<<"捕获到char类型异常 e = "<<e<<endl;
}
catch(char const *e)//只捕获 抛出是char *类型的异常
{
cout<<"捕获到char const *类型异常 e = "<<e<<endl;
}
catch(string e)
{
cout<<"捕获到string类型异常 e = "<<e<<endl;
}
}
知识点4【异常的生命周期】
推荐这种方式:
知识点5【标准异常】
知识点6【cin的拓展】
1、cin.get获取一个字符,cin.getline获取带空格的字符串
#include <iostream>
#include<string>
using namespace std;
void test07(){
int data = 0;
cin >> data;
cout << "data = " << data << endl;
char ch;
cin >> ch;
cout << "ch = " << ch << endl;
//获取一个字符
char ch1 = 'd';
ch1 = cin.get();
cout<<"ch1 = "<<ch1<<endl;
char name[128]="ddddd";
cin>>name;//遇到空格 回车结束获取
cout<<"name="<<name<<endl;
char name2[128]="sss";
cin.getline(name2,sizeof(name));//可以获取带空格的字符串
cout<<"name = "<<name2<<endl;
}
int main(int argc, char *argv[])
{
test07();
return 0;
}
2、cin.ignore忽略 缓冲区的前 n个字符
3、cin.putback放回缓冲区
4、cin.peek偷窥