Day35.C++09

Day35.C++09

01.类型转换-静态类型和动态转换和常量转换

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

//静态转换
//基础类型
void test01()
{
	char a = 'a';
	double d = static_cast<double>(a);

	cout << "d = " << d << endl;
}

//父子之间的转换
class Base{};
class Child :public Base{};
class Other{};

void test02()
{
	Base* base = NULL;
	Child* child = NULL;

	//把base*转为Child* 类型,向下,不安全
	Child* child2 = static_cast<Child*>(base);

	//把Child*转为base* 类型,向上,安全
	Base* base2 = static_cast<Base*>(child);

	//转Other*类型  类Other与类Base之间不存在父子关系,不可以转换类型
	//Other* other = static_cast<Other*>(base);
}
//static_cast 的使用   static_cast<目标类型>(原始对象)


//动态转换
void test03()
{
	//基础类型不可以动态转换
	char c = 'a';
	//dynamic_cast 非常严格 ,失去精度或者 不安全,都不可以转换
	//double d = dynamic_cast<double>(c);
}

class Base2 {
	virtual void func() {}
};
class Child2:public Base2{
	virtual void func() {}
};
class Other2 {};

void test04()
{
	Base2* base = NULL;
	Child2* child = NULL;
	//Child*转Base*  安全
	Base2* base2 = dynamic_cast<Base2*>(child);

	//Base*转Child*  不安全
	//Child2* child2 = dynamic_cast<Child2*>(base);

	//如果发生了多态,那么可以让基类转为派生类,向下转换
	Base2* base3 = new Child2;
	Child2* child3 = dynamic_cast<Child2*>(base3);
}

//常量转换(const_cast)
void test05()
{
	const int* p = NULL;
	//去除const
	int* newP = const_cast<int*>(p);

	int* p2 = NULL;
	const int* newP2 = const_cast<const int*>(p2);

	//不能对非指针 或者 非引用的变量进行转换

}



int main(void)
{
	test01();


	system("pause");
	return EXIT_SUCCESS;
}

02.异常的基本处理

总结:

try 试图执行 try{} 中的内容
在可能出现已成的地方 抛出异常 throw
try下面 catch 捕获异常
catch(捕获类型)  ...代表 所有其他的类型
如果不想处理异常,继续向上抛出,throw
如果没有任何处理异常的地方,那么程序调用terminate函数中断程序

自定义异常类,可以抛出自定义的对象,捕获自定义的异常
从try开始,到throw抛出异常之前,所有栈上的对象,都会被释放,这个过程为栈解旋
异常的接口声明:如果想抛出特定的类型异常,可以利用异常的接口声明
void func() throw(int,char){}  //只能抛出int 或者 char 类型的异常
void func() throw(){}  //不抛出任何类型的异常

代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class myException//自定义异常类
{
public:
	void printError()
	{
		cout << "自定义的异常" << endl;
	}
};

int myDevide(int a, int b)
{
	if (b == 0)
	{
		//throw -1;//抛出int类型异常,异常必须处理,如果不处理,就会挂掉
		//throw 3.14;

		//栈解旋
		//从try开始,到throw抛出异常之前,所有栈上的对象,都会被释放,这个过程为栈解旋


		throw myException();
	}
	return a / b;
}

void test01()
{
	int a = 10;
	int b = 0;

	try
	{
		cout << myDevide(a, b) << endl;

	}
	catch (int)
	{
		cout << "int类型异常捕获" << endl;
		cout << "除数为0,无解" << endl;
	}
	catch (double)
	{
		throw;
		cout << "double类型异常捕获" << endl;
		cout << "除数为0,无解" << endl;
	}
	catch (myException e)
	{
		e.printError();
	}
	catch (...)
	{
		cout << "其他类型异常捕获" << endl;
	}
}

int main(void)
{
	try
	{
		test01();
	}
	catch (double)
	{
		cout << "main函数中 double类型异常捕获!" << endl;
	}

	system("pause");
	return EXIT_SUCCESS;
}

03.异常变量生命周期

- 如果MyException e,会多开销一份数据,调用拷贝构造
- 如果MyException* e ,不new 提前释放对象,new 的话需要自己管理 delete
- 推荐MyException& e,容易些,而且不会创建多余的数据

04.使用系统提供的标准异常

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<stdexcept>
#include<string>

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		if (age < 0 || age>200)
		{
			//抛出越界异常
			throw out_of_range("年龄越界了!");
		}
		this->m_Age = age;
	}


	string m_Name;
	int m_Age;
};

void test01()
{
	Person p("孙猴子", 500);
}

int main(void)
{
	try
	{
		test01();
	}
	catch (out_of_range& e)
	{
		cout << e.what() << endl;
	}

	system("pause");
	return EXIT_SUCCESS;
}

05.自己编写异常类

总结:

- 自己的异常类 , 需要继承于 exception
- 需要重写  虚析构 和 what()
- 内部维护一个错误信息字符串
- 构造时候传入 错误信息字符串 ,what()返回 错误信息字符串
- string 转 char*    c_str()

代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<string>

class myOutOfRangeException :public exception
{
public:

	myOutOfRangeException(string errorInfo)
	{
		this->m_ErrorInfo = errorInfo;
	}

	virtual ~myOutOfRangeException()
	{

	}
	virtual const char* what() const
	{
		//返回 错误信息
		//string 转char*    c_str()
		return this->m_ErrorInfo.c_str();
	}
	string m_ErrorInfo;
};

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		if (age < 0 || age>200)
		{
			//抛出异常
			throw myOutOfRangeException("年龄越界了!");
		}
		this->m_Age = age;
	}


	string m_Name;
	int m_Age;
};

void test01()
{
	try {
	
		Person p("孙猴子", 500);
	}
	catch(myOutOfRangeException& e)
	{
		cout << e.what() << endl;
	}
}

int main(void)
{
	test01();

	system("pause");
	return EXIT_SUCCESS;
}

06.标准输入流(不常用)

总结:

cin.get() //一次只能读取一个字符
cin.get(一个参数) //读一个字符
cin.get(两个参数) //可以读字符串
cin.getline() //读取换行,并且扔掉
cin.ignore(N) //N代表忽略的字符数, 没有参数时忽略一个字符
cin.peak() //偷窥 偷看一个字符,然后放回去
cin.putback() //放回 把字符放回缓冲区

代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

/*
cin.get()		  //一次只能读取一个字符
cin.get(一个参数) //读一个字符
cin.get(两个参数) //可以读字符串
cin.getline()     //读取换行,并且扔掉
cin.ignore(N)	  //N代表忽略的字符数, 没有参数时忽略一个字符
cin.peak()		  //偷窥 偷看一个字符,然后放回去
cin.putback()	  //放回 把字符放回缓冲区
*/

void test01()
{
	//cin.get() //一次只能读取一个字符
	char c = cin.get();
	cout << "c = " << c << endl;

	c = cin.get();
	cout << "c = " << c << endl;
}

void test02()
{
	//cin.get(两个参数) //可以读字符串
	char buf[1024];
	cin.get(buf, 1024);
	char c = cin.get();

	if (c == '\n')
	{
		cout << "换行还在缓冲区" << endl;
	}
	else
	{
		cout << "换行不在缓冲区了" << endl;
	}

	cout << buf << endl;
}
//cin.get(两个参数)读取字符串时,不会把换行符拿走,遗留在缓冲区中

void test03()
{
	//cin.getline();
	char buf[1024];
	cin.getline(buf, 1024);
	
	//换行不在缓冲区了
	//cin.getline() 把换行符读取,并且扔掉
	

	cout << buf << endl;
}

void test04()
{
	//cin.ignore() 忽略
	cin.ignore(2);//没有参数代表忽略一个字符,带参数N表示忽略N个字符

	char c = cin.get();
	cout << "c = " << c << endl;
}

void test05()
{
	//cin.peek() 偷窥
	//输入as

	char c = cin.peek();
	cout << "c = " << c << endl;
	c = cin.get();
	cout << "c = " << c << endl;
}

void test06()
{
	//cin.putback();
	char c = cin.get();
	cin.putback(c);
	cout << "c = " << c << endl;

	char buf[1024];
	cin.getline(buf, 1024);

	cout << "buf = " << buf << endl;
	
}


int main(void)
{
	//test01();
	//test02();
	//test03();
	//test04();
	//test05();
	test06();


	system("pause");
	return EXIT_SUCCESS;
}

07.标准输入案例

//案例1:判断用户输入的是数字还是字符串
void test07()
{
	cout << "请输入一串数字或者字符串" << endl;

	//偷窥
	char c = cin.peek();

	if (c >= '0' && c <= '9')
	{
		int num;
		cin >> num;
		cout << "宁输入的是数字:输入的数字为" << num << endl;
	}
	else
	{
		char buf[1024];
		cin >> buf;

		cout << "宁输入的是字符串:输入的字符串为" << buf << endl;
	}

}

//案例二:让用户输入 1-10 的数字,如果输入有误 重新输入(测试有问题,未解决)
void test08()
{
	int num;
	cout << "请输入 1到10 的数字:" << endl;

	while (true)
	{
		cin >> num;
		if (num > 0 && num <= 10)
		{
			cout << "输入的数字为:" << num << endl;
			break;
		}
		cout << "对不起,输入的数字有误,请重新输入:" << endl;
		//重置标志位
		cin.clear();
		//清空缓冲区
		cin.sync();
		//cout << "标志位" << cin.fail() << endl;//标志位为0 是正常的,1 不正常
		
	}
}

08.标准输出流(不常用)

流对象的成员函数:

int number = 99;
cout.width(20);
cout.fill('*');
cout.setf(ios::left);//设置格式,输出内容左对齐
cout.unsetf(ios::dec);//卸载十进制
cout.setf(ios::hex);//安装十六进制
cout.setf(ios::showbase);//强制输出整数基数
cout.unsetf(ios::hex);
cout.setf(ios::oct);
cout << number << endl;

09.文件的读写操作

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//文件读写头文件
#include<fstream>

//写文件
void test01()
{
	//以输出的方式打开文件
	//ofstream ofs("./test.txt", ios::out | ios::trunc);

	//后期指定打开方式
	ofstream ofs;
	ofs.open("./test.txt", ios::out | ios::trunc);
	//判断是否打开成功
	if (!ofs.is_open())
	{
		cout << "打开失败!" << endl;
	}
	ofs << "姓名:abc" << endl;
	ofs << "年龄:10" << endl;
	ofs << "性别:男" << endl;

	ofs.close();
}

//文件写操作
void test02()
{
	ifstream ifs;
	ifs.open("./test.txt", ios::in);

	//判断是否打开成功
	if (!ifs.is_open())
	{
		cout << "打开失败" << endl;
	}
	第一种方式
	//char buf[1024];
	//while (ifs >> buf)//按行读取
	//{
	//	cout << buf << endl;
	//}

	第二种方式
	//char buf2[1024];
	//while (!ifs.eof())//eof 读到文件尾部
	//{
	//	ifs.getline(buf2, sizeof(buf2));
	//	cout << buf2 << endl;
	//}

	//第三种方式:按单个字符读取(不推荐)
	char c;
	while ((c = ifs.get()) != EOF) //EOF 文件尾
	{
		cout << c;
	}
	ifs.close();
}

int main(void)
{
	//test01();
	test02();

	system("pause");
	return EXIT_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值