
类型转换
静态转换 static_case
使用方式:static_case<目标类型> (原始数据)
可以进行基础数据类型和父子之间的转换
没有父子关系的自定义类型不能静态转换
动态转换 dynamic_case
不可以转换基础类型
dynamic_cast非常严格,失去精度或者不安全都不可转换
父子之间:
父转子:不可以
子转父:可以
发生多态:都可以
常量转换 const_cast
不能对非指针或者非引用的变量就进行转换
重新解释转换 reinterpret_cast
最不安全,不推荐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
using namespace std;
void () { char a = 'a'; double d = static_cast<double>(a); cout<<"d= "<<d<<endl; }
class Base { virtual void func(){} }; class Child :public Base { virtual void func(){} }; class Other{};
void test02() { Base *base = NULL; Child *child = NULL;
Child *child2 = static_cast<Child*>(base); Base *base2 = static_cast<Base*>(child);
}
void test03() { char c = 'a'; }
void test04() { Base *base = NULL; Child *child = NULL;
Base *base2 = dynamic_cast<Base*>(child);
Base *base3 = new Child; Child *child3 = dynamic_cast<Child*>(base3);
}
void test05() { const int *p = NULL; int *newp = const_cast<int *>(p);
int *p2 = NULL; const int *newp2 = const_cast<const int *>(p2);
int num = 10; int &numref = num; const int &numref2 = const_cast<const int &>(numref); }
void test06() { int a = 10; int *p = reinterpret_cast<int *>(a);
Base *base = NULL; Other *other = reinterpret_cast<Other *>(base); } int main(void) { test01(); return 0; }
|
类型异常的基本使用
try试图执行try{}中的内容
在可能出现异常的地方抛出异常 throw
try下面catch捕获异常
catch( 捕获类型 ) … 代表所有其他类型
如果不想处理异常,继续向上抛出 throw;
如果没有任何处理异常的地方,那么成员调用terminate函数,中断程序
自定义异常类,可以抛出自定义的对象,捕获这种自定义的异常
栈解旋:从try开始到throw抛出异常之前,所有栈上的对象都会被释放的过程
栈上构造顺序和析构顺序相反
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
using namespace std;
class myException //自定义异常类 { public: void printError() { cout<<"自定义的异常"<<endl; } };
class Person {
public: Person() { cout<<"构造函数调用"<<endl; } ~Person() { cout<<"析构函数调用"<<endl; } }; int myDevide(int a, int b) { if(b == 0) { Person p1, p2; throw myException(); } return a/b; } void test() { int a = 10; int b = 0;
try { myDevide(a, b); } catch(int) { cout<<"int类型异常捕获"<<endl; } catch(double) { throw; cout<<"double类型异常捕获"<<endl; } catch(myException e) { e.printError(); } catch(...) { cout<<"其他类型异常捕获"<<endl; } }
int main(void) {
try { test(); } catch(double) { cout<<"main函数中double类型异常捕获"<<endl; } catch(...) { cout<<"main函数中其他类型异常捕获"<<endl; } return 0; }
|
异常的接口声明
如果想抛出特定的异常,可以利用异常的接口声明
throw()不抛出任何异常
1 2 3 4 5 6 7 8 9
|
void func() throw(int) { throw 1; }
void func() throw(int,char,double) { throw 1; }
|
异常变量的生命周期
如果 MyException e,会多开销一份数据
如果 MyException *e,不new会提前释放对象,new的话要自己释放对象delete
推荐 MyException &e, 容易些,而且就一份数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
using namespace std;
class MyException {
public: MyException() { cout<<"MyException的默认构造"<<endl; } MyException(const MyException &myexception) { cout<<"MyException的拷贝构造"<<endl; } ~MyException() { cout<<"MyException的析构调用"<<endl; } };
void doWork() { throw new MyException(); } void test() { try { doWork(); } catch(MyException *e) { cout<<"捕获异常"<<endl;
delete e; } }
int main(void) { test(); return 0; }
|
异常的多态使用
利用多态来实现printError同一个接口的使用
抛出不同的错误对象,提示不同的错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
using namespace std;
class BaseException { public: virtual void printError() {
} };
class NullPointerException :public BaseException { public: virtual void printError() { cout<<"空指针异常"<<endl; } };
class OutofRangeException :public BaseException { public: virtual void printError() { cout<<"越界异常"<<endl; } };
void doWork() { throw NullPointerException(); } void test() { try { doWork(); } catch(BaseException &e) { e.printError(); } }
int main(void) { test(); return 0; }
|
系统提供的标准异常
系统提供标准异常,要包含头文件#include < stdexcept >
throw out_of_range(“年龄越界了”);
catch(out_of_range &e){ cout<<e.what()<<endl; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
using namespace std;
#include <stdexcept> class Person { public: Person(string name, int age) { this->m_Name = name; if(age<0 || age>200) { throw length_error("长度越界了"); }
} ~Person(){}
string m_Name; int m_Age; }; void test() { try { Person p("张三", 222); } catch(out_of_range &e) { cout<<e.what()<<endl; } catch(length_error &e) { cout<<e.what()<<endl; } }
int main(void) { test(); return 0; }
|
编写自己的异常类
自己的异常类需要继承于 exception 类
重写 虚析构 和 what()函数
内部维护以错误信息 字符串
构造的时候传入 错误信息字符串,在what方法返回这个字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
#include <iostream> using namespace std;
class MyOutofRangeException :public exception { public: MyOutofRangeException(string effInfo) { this->m_ErrorInfo = effInfo; } virtual ~MyOutofRangeException() {
} virtual char const* what() const throw() { 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("我自己的越界异常"); }
} ~Person(){}
string m_Name; int m_Age; }; void test() { try { Person p("张三", 222); } catch(MyOutofRangeException &e) { cout<<e.what()<<endl; } }
int main(void) { test(); return 0; }
|
标准输入流
cin.get()缓冲区中读取一个字符
cin.get(两个参数)不读换行符
cin.getline()读取换行,并且扔掉
cin.ignore() 忽略(N)N代表忽略字符数
cin.peek()偷窥 偷看1个字符然后放回去
cin.putback()放回,把字符放回缓冲区
输入流案例
-
判断用户输入的是字符串还是数字,利用偷窥或者放回
-
让用户输入指定返回内的数字,如果输入不正确,重新输入
cin.fail() 标志位 0正常 1不正常
cin.clear() 重置标志位
cin.sync() 清空缓冲区
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#include <iostream> using namespace std;
void () { 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]; cin.get(buf, 1024); char c = cin.get(); if (c == 'n') { cout << "换行还在缓冲区" << endl; } else { cout << "换行不在缓冲区" << endl; }
cout << buf << endl; }
void test03() { char buf[1024]; cin.getline(buf, 1024); char c = cin.get(); if (c == 'n') { cout << "换行还在缓冲区" << endl; } else { cout << "换行不在缓冲区" << endl; } cout << buf << endl; }
void test04() { cin.ignore(); char c = cin.get(); cout << "c= " << c << endl; }
void test05() { char c = cin.peek(); cout << "c= " << c << endl;
c = cin.get(); cout << "c= " << c << endl; }
void test06() { char c = cin.get(); cin.putback(c);
char buf[1044]; cin.getline(buf, 1024); cout << buf << endl; }
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; } }
void test08() { int num;
while (true) { cin >> num; if (num > 0 && num < 10) { cout << "输入的数字为: " << num << endl; break; } cout << "对不起,请重新输入" << endl; cin.clear(); cin.sync(); } } int main(void) { test08(); return 0; }
|
标准输出流
流对象的成员函数
控制符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
#include <iostream> #include <cstring> #include <iomanip> using namespace std;
void () { cout.put('a').put('b') << endl;
char buf[1024] = "helloworld"; cout.write(buf, strlen(buf)); }
void test02() {
int num = 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 << num << endl; } void test03() { int num = 99; cout << setw(20) <<setfill('~') << setiosflags(ios::showbase) <<setiosflags(ios::left) << hex << num << endl; } int main(void) { test03(); return 0; }
|
文件读写
写文件
ofstream ofs;
open 指定打开方式
is_open()判断是否打开成功
ofs<<”数据”
ofs.close();
读文件
ifstream ifs;
指定方式打开
判断是否打开成功
三种方式读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
#include <iostream> #include <fstream> #include <cstring> using namespace std;
void () {
ofstream ofs; ofs.open("./test.txt", ios::out | ios::trunc); if(!ofs.is_open()) { cout<<"打开失败"<<endl; }
ofs<<"姓名:abc"<<endl; ofs<<"年龄:100"<<endl; ofs<<"性别:男"<<endl; }
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()) { ifs.getline(buf2, sizeof(buf2)); cout<<buf2<<endl; } char c; while((c = ifs.get()) != EOF) { cout<<c; } }
int main(void) { test01(); test02(); return 0; }
|
近期评论