C++Day9

C++Day9

静态类型转换static_cast

#include <iostream>
using namespace std;

//静态类型转换 static_cast
void test01()
{
	//允许内置数据类型之间转换
	char a = 'a';
	double d = static_cast<double>(a);
	cout << d << endl;
}

class Base{};
class Son : public Base{};
class Other{};

void test02()
{
	Base* base = NULL;
	Son* son = NULL;

	//语法:static_cast<目标类型>(原对象)
	//父子之间的指针或引用可以转换
	//将base转为son 父转子 向下类型转换 不安全 但仍可以转换
	Son* son2 = static_cast<Son*>(base);

	//son转为base* 子转父 向上类型转换 安全
	Base* base2 = static_cast<Base*>(son);

	//base转为Other*无法转换
	//Other* other = static_cast<Other*>(base);
}

int main()
{
	test01();
	return EXIT_SUCCESS;
}

动态类型转换dynamic_cast

  • 主要用于类层次间的上行转换和下行转换
  • 在类层次间进行上行转换时,dynamic_cast和static_cast的效果一样
  • 在进行下行转换时,dynamic_cast具有类型检查的功能
#include <iostream>
using namespace std;

//动态类型转换dynamic_cast
void test01()
{
	//不允许内置数据类型之间转换
	//char c='c';
	//double d=dynamic_cast<double>(c);
}

class Base { virtual void func() {} };
class Son : public Base { virtual void func() {} };
class Other {};

void test02()
{
	Base* base = new Son;
	Son* son = NULL;

	//将base转为Son* 父转子 不安全 无效转换
	//如果发生了多态 那么转换总是安全的
	//Son * son2=dynamic_cast<Son*>(base);

	//son转为Base* 子转父 安全
	Base* base2 = dynamic_cast<Base*>(son);

	//base转为Other* 无效转换
	//Other* other = dynamic_cast<Other*>(base);
}

int main()
{
	test01();
	test02();
	return EXIT_SUCCESS;
}

常量转换和重新解释转换

#include <iostream>
using namespace std;

//常量转换const_cast
void test01()
{
	//不可以将非指针或非引用做const_cast转换
	const int* p = NULL;
	int* pp = const_cast<int*>(p);
	const int* ppp = const_cast<const int*>(pp);

	//const int a=10;
	//int b=const_cast<int>(a);

	int num = 10;
	int& numRef = num;

	const int& num2 = const_cast<const int&>(numRef);
}

int main()
{
	test01();
	return EXIT_SUCCESS;
}
  • 重新解释转换reinterpret——cast

    • 最不安全的一种转换机制

    • 用于将一种数据类型从一种数据类型转换为另一种类型,可将一个指针转换为一个整数,也可将一个整数转换为一个指针

    • #include <iostream>
      using namespace std;
      
      class Base{};
      class Other{};
      
      //重新解释转换
      void test01()
      {
      	int a = 10;
      	int* p = reinterpret_cast<int*>(a);
      
      	Base* base = NULL;
      	//base转为Other*
      	Other* other = reinterpret_cast<Other*>(base);
      }
      
      int main()
      {
      	test01();
      	return EXIT_SUCCESS;
      }
      

异常的基本语法

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

class MyException
{
public:
	void printError()
	{
		cout << "我自己的异常" << endl;
	}
};

class Person
{
public:
	Person()
	{
		cout << "Person的默认构造函数调用" << endl;
	}
	~Person()
	{
		cout << "Person的析构函数调用" << endl;
	}
};

int myDivision(int a , int b)
{
	if ( b == 0)
	{
		//return -1;
		//throw 1; //抛出int类型的异常
		//throw 'a'; //抛出char类型的异常
		//throw 3.14; //抛出double类型的异常
		/*string str = "abc";
		throw str;*/


		//从try代码块开始,到throw抛出异常之前,所有栈上的数据都会被释放掉,
		//释放的顺序和创建顺序相反的,这个过程我们称为栈解旋
		Person p1;
		Person p2;


		throw MyException(); //抛出 MyException的匿名对象
	}

	return a / b;
}

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

	//C语言处理异常 有缺陷:返回值不统一,返回值只有一个,无法区分是结果还是异常
	//int ret =myDivision(a, b);
	//if ( ret == -1)
	//{
	//	cout << "异常" << endl;
	//}

	try
	{
		myDivision(a, b);
	}
	catch (int)
	{
		cout << "int类型异常捕获" << endl;
	}
	catch (char)
	{
		cout << "char类型异常捕获" << endl;
	}
	catch (double)
	{
		//捕获到了异常,但是不想处理,继续向上抛出这个异常
		//异常必须有函数进行处理,如果没有任何处理,程序自动调用 terminate 函数,让程序中断
		throw;
		cout << "double类型异常捕获" << endl;
	}
	catch (MyException e)
	{
		e.printError();
	}
	catch (...)
	{
		cout << "其他类型异常捕获" << endl;
	}
	
}

int main(){

	try
	{
		test01();
	}
	catch (double)
	{
		cout << "double函数中 double类型异常捕获" << endl;
	}
	catch (...)
	{
		cout << "main函数中 其他类型异常捕获" << endl;
	}
	return EXIT_SUCCESS;
}

异常变量的生命周期

#include<iostream>
using namespace std;

class MyException
{
public:
	MyException()
	{
		cout << "MyException默认构造函数调用" << endl;
	}

	MyException(const MyException & e)
	{
		cout << "MyException拷贝构造函数调用" << endl;
	}

	~MyException()
	{
		cout << "MyException析构函数调用" << endl;
	}

};

void doWork()
{
	throw  new MyException();
}

void test01()
{
	try
	{
		doWork();
	}
	//抛出的是 throw MyException();  catch (MyException e) 调用拷贝构造函数 效率低
	//抛出的是 throw MyException();  catch (MyException &e)  只调用默认构造函数 效率高 推荐
	//抛出的是 throw &MyException(); catch (MyException *e) 对象会提前释放掉,不能在非法操作
	//抛出的是 new MyException();   catch (MyException *e) 只调用默认构造函数 自己要管理释放
	catch (MyException *e)
	{
		cout << "自定义异常捕获" << endl;
		delete e;
	}

}

int main(){
	test01();
	return EXIT_SUCCESS;
}

异常的多态使用

#include<iostream>
using namespace std;

//异常的基类
class BaseException
{
public:
	virtual void printError() = 0;
};

//空指针异常
class NULLPointerException :public BaseException
{
public:
	virtual void printError()
	{
		cout << "空指针异常" << endl;
	}
};

//越界异常
class OutOfRangeException :public BaseException
{
public:
	virtual void printError()
	{
		cout << "越界异常" << endl;
	}

};

void doWork()
{
	//throw NULLPointerException();
	throw OutOfRangeException();
}

void test01()
{
	try
	{
		doWork();
	}
	catch (BaseException & e)
	{
		e.printError();
	}
}


int main(){

	test01();
	return EXIT_SUCCESS;
}

系统标准异常

#include<iostream>
using namespace std;
#include <stdexcept> //  std 标准  except 异常
class Person
{
public:
	Person(int age)
	{
		if (age < 0 || age > 150)
		{
			throw out_of_range("年龄必须在 0 ~ 150之间");
			//throw length_error("年龄必须在 0 ~ 150之间");
		}
		else
		{
			this->m_Age = age;
		}
	}

	int m_Age;
};

void test01()
{
	try
	{
		Person p(151);
	}
	//catch ( out_of_range &e)
	catch ( exception &e)
	{
		cout << e.what() << endl;
	}

}

int main(){
	test01();
	return EXIT_SUCCESS;
}

标准输入流

#include<iostream>
using namespace std;

/*
cin.get() //一次只能读取一个字符
cin.get(一个参数) //读一个字符
cin.get(两个参数) //可以读字符串
cin.getline()
cin.ignore()
cin.peek()
cin.putback()
*/
void test01()
{
	//输入  a  s     第一次 a  第二次  s  第三次 换行  第四次 等待下次输入
	char c = cin.get();

	cout << "c = " << c << endl;

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

	c = cin.get();

	cout << "c = " << c << endl;


	c = cin.get();

	cout << "c = " << c << endl;
}


void test02()
{
	char buf[1024] = { 0 };
	cin.get(buf, 1024);

	char c = cin.get();
	//利用cin.get获取字符串时候,换行符遗留在缓冲区中
	if (  c== '\n')
	{
		cout << "换行符遗留在缓冲区" << endl;
	}
	else
	{
		cout << "换行符不在缓冲区" << endl;
	}
	cout << buf << endl;

}

void test03()
{
	char buf[1024] = { 0 };

	//利用cin.getline获取字符串时候,换行符不会被取走,也不在缓冲区中,而是直接扔掉
	cin.getline(buf, 1024);

	char c = cin.get();
	if (c == '\n')
	{
		cout << "换行符遗留在缓冲区" << endl;
	}
	else
	{
		cout << "换行符不在缓冲区" << endl;
	}
	cout << buf << endl;

}

//cin.ignore() 忽略 默认忽略1个字符, 如果填入参数X,代表忽略X个字符
void test04()
{
	cin.ignore(2);
	char c = cin.get();
	cout << "c = " << c << endl;
}

//cin.peek() 偷窥
void test05()
{
	char c = cin.peek();
	cout << "c = " << c << endl;

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

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

}

//cin.putback() 放回
void test06()
{
	char c = cin.get();
	cin.putback(c);

	char buf[1024] = { 0 };

	cin.getline(buf, 1024);
	cout << buf << endl;
}


//案例1、 判断用户输入的内容 是字符串还是数字  12345     abcde
void test07()
{
	cout << "请输入一个字符串或者数字" << endl;
	char c = cin.peek();

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

//案例2、 用户输入 0 ~ 10 之间的数字,如果输入有误,重新输入
void test08()
{
	cout << "请输入 0 ~ 10 之间的数字" << endl;

	int num;

	while (true)
	{
		cin >> num;

		if (num >= 0 && num <= 10)
		{
			cout << "输入正确,输入值为:" << num << endl;
			break;
		}
		
		//清空缓冲区 重置标志位 
		cin.clear();
		cin.sync();
		//cin.ignore();//vs2013以上版本加入 
		//如果标志位为 0  代表缓冲区正常    如果标志位为1   缓冲区异常
		//cout << " cin.fail()  = " << cin.fail() << endl;
		
		cout << "输入有误,请重新输入: " << endl;
	}

}

int main(){
	//test01();
	//test02();
	//test03();
	//test04();
	//test05();
	//test06();
	//test07();
	test08();
	return EXIT_SUCCESS;
}

标准输出流

#include<iostream>
using namespace std;
#include <iomanip> //控制符格式化输出  头文件

/*
cout.put() //向缓冲区写字符
cout.write() //从buffer中写num个字节到当前输出流中。
*/
void test01()
{
	//cout.put('h').put('e');

	char buf[] = "hello world";
	cout.write(buf, strlen(buf));

	cout << "hello world" << endl;

}

//1、通过 流成员函数 格式化输出
void test02()
{
	int number = 99;
	cout.width(20); //指定宽度为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;
}

//2、使用控制符 格式化输出
void test03()
{
	int number = 99;
	cout << setw(20)     //设置宽度
		<< setfill('~')  //设置填充
		<< setiosflags(ios::showbase)  //显示基数
		<< setiosflags(ios::left)  //设置左对齐
		<< hex   //显示十六进制
		<< number
		<< endl;


}

int main(){

	//test01();
	//test02();
	test03();
	return EXIT_SUCCESS;
}

文件读写

#include<iostream>
using namespace std;
#include <fstream> //文件流
#include <string>

void test01()
{
	//写文件  o --  输出    
	ofstream  ofs("./test.txt", ios::out | ios::trunc);

	//ofs.open("./test.txt", ios::out | ios::trunc);  设置打开方式 以及路径

	if (!ofs.is_open())
	{
		cout << "文件打开失败" << endl;
		return;
	}

	ofs << "姓名:孙悟空" << endl;
	ofs << "年龄:999" << endl;
	ofs << "性别:男" << endl;

	//关闭文件
	ofs.close();

}


void test02()
{
	//读文件   i  -- 输入
	ifstream  ifs;
	ifs.open("./test.txt", ios::in);

	if (!ifs.is_open())
	{
		cout << "文件打开失败" << endl;
		return;
	}

	//第一种方式
	//char buf[1024] = { 0 };

	//while (ifs >> buf)
	//{
	//	cout << buf << endl;
	//}


	//第二种方式
	//char buf[1024] = { 0 };
	//while (ifs.getline(buf,sizeof(buf)))
	//{
	//	cout << buf << endl;
	//}

	//第三种方式
	//string buf;
	//while ( getline(ifs,buf) )
	//{
	//	cout << buf << endl;
	//}


	//第四种方式
	char  c;
	while ( (c = ifs.get()) != EOF )
	{
		cout << c;
	}

	ifs.close();
}

int main(){

	//test01();
	test02();
	return EXIT_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值