day8: coding

This commit is contained in:
flykhan 2023-08-02 19:23:29 +08:00
parent 994963d919
commit 606fbc6ff1
17 changed files with 842 additions and 0 deletions

21
day8/d1.cpp Normal file
View File

@ -0,0 +1,21 @@
// 抛出异常
#include <iostream>
using namespace std;
int div(int a, int b)
{
if (b == 0)
{
throw "除数不能为0";
}
return a / b;
}
int main()
{
cout << "-----aaaaa-----" << endl;
int ret = div(20, 0);
cout << ret << endl;
return 0;
}

81
day8/d10.cpp Normal file
View File

@ -0,0 +1,81 @@
// 异常的多态
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class Exception
{
private:
string msg;
public:
Exception()
{
this->msg = "";
cout << this << " : Exception()" << endl;
}
Exception(const string &msg)
{
this->msg = msg;
cout << this << " : Exception(const string &)" << endl;
}
Exception(const Exception &other)
{
this->msg = other.msg;
cout << this << " : Exception(const Exception &)" << endl;
}
~Exception() { cout << this << " : ~Exception()" << endl; }
public:
string &getMsg() // const 表示该成员函数不会修改成员变量
{
return this->msg;
}
};
class ZeroDivisionException : public Exception
{
public:
ZeroDivisionException() {}
ZeroDivisionException(const string &msg) : Exception(msg) {}
};
class OutOfRangeException : public Exception
{
public:
OutOfRangeException() {}
OutOfRangeException(const string &msg) : Exception(msg) {}
};
int main(int argc, char const *argv[])
{
int n = atoi(argv[1]);
try
{
if (n == 0)
// 抛出子类的异常对象
throw ZeroDivisionException("除数为不能 0");
else if (n >= 20)
throw OutOfRangeException("范围越界 20");
else if (n == 10)
throw Exception("n 不能为 10");
else
cout << "n = " << n << endl;
}
catch (ZeroDivisionException &error) // 接子类引用
{
cout << "精准捕获到子类异常: " << error.getMsg() << endl;
}
catch (Exception &e) // 接父类引用(要写到子类异常的后面)
{
cout << "捕获异常: " << e.getMsg() << endl;
}
catch (...) // 捕获所有异常
{
cout << "捕获所有异常" << endl;
}
return 0;
}

37
day8/d11.cpp Normal file
View File

@ -0,0 +1,37 @@
// exception 的使用
// invalid_argument: 用于处理无效参数异常
#include <iostream>
#include <cstdlib>
#include <exception>
#include <cstdio>
using namespace std;
int maxVal(int a, int b)
{
if (a == b)
{
char msg[100];
sprintf(msg, "两个参数不能相等a = %d, b = %d", a, b);
throw invalid_argument(msg);
}
return a > b ? a : b;
}
int main(int argc, char const *argv[])
{
int a = atoi(argv[1]);
int b = atoi(argv[2]);
try
{
int ret = maxVal(a, b);
cout << "maxValue is " << ret << endl;
}
catch (exception &error)
{
cout << "error: " << error.what() << endl; // what() 返回异常信息,异常信息是一个字符串
}
return 0;
}

83
day8/d12.cpp Normal file
View File

@ -0,0 +1,83 @@
// 异常与模版
// 异常处理循环问题的示例
#include <iostream>
#include <exception>
using namespace std;
template <typename T>
class Stack
{
private:
T *mData; // 数据
int mCapacity; // 容量
int mIndex; // 索引
public:
// -1 表示栈为空
Stack(int capacity) : mCapacity(capacity), mIndex(-1)
{
this->mData = new T[this->mCapacity];
}
~Stack()
{
delete[] this->mData; // 释放内存
mData = nullptr; // 防止野指针
}
public:
T pop() throw(out_of_range)
{
if (mIndex < 0)
throw out_of_range("当前栈未空,请先压栈");
return this->mData[this->mIndex--];
}
Stack<T> &push(const T &item) throw(out_of_range)
{
if (mIndex >= mCapacity - 1) // >= 表示栈满 , mCapacity - 1 表示栈顶
throw out_of_range("当前栈已满,请先出栈");
this->mData[++this->mIndex] = item;
return *this; // 返回当前对象,支持链式编程
}
T &at(int index) throw(out_of_range)
{
// mIndex == -1 表示栈为空index < 0 表示索引小于 0index > mIndex 表示索引大于栈顶
if (mIndex == -1 || index < 0 || index > mIndex)
throw out_of_range("当前栈为空或位置无效");
return this->mData[index];
}
int size() const
{
return this->mIndex + 1;
}
};
int main()
{
Stack<int> s1(5);
s1.push(10).push(20).push(30);
for (int i = 0; i < s1.size(); i++)
cout << s1.at(i) << endl;
cout << "*** 弹出数据 ***" << endl;
// 清空数据
while (1)
{
try
{
cout << s1.pop() << endl;
}
catch (exception &e)
{
cout << "error: " << e.what() << endl;
break; // 异常处理: 跳出循环
}
}
cout << "*** 弹栈完成,重新打印 ***" << endl;
for (int i = 0; i < s1.size(); i++)
cout << s1.at(i) << endl;
return 0;
}

91
day8/d13.cpp Normal file
View File

@ -0,0 +1,91 @@
// 自定义标准异常类
#include <iostream>
#include <exception>
using namespace std;
class OutOfRangeError : public exception
{
public:
virtual const char *what() const throw()
{
return "访问索引越界";
}
};
template <typename T>
class Stack
{
private:
T *mData; // 数据
int mCapacity; // 容量
int mIndex; // 索引
public:
// -1 表示栈为空
Stack(int capacity) : mCapacity(capacity), mIndex(-1)
{
this->mData = new T[this->mCapacity];
}
~Stack()
{
delete[] this->mData; // 释放内存
mData = nullptr; // 防止野指针
}
public:
T pop() throw(OutOfRangeError)
{
if (mIndex < 0)
throw OutOfRangeError();
return this->mData[this->mIndex--];
}
Stack<T> &push(const T &item) throw(OutOfRangeError)
{
if (mIndex >= mCapacity - 1) // >= 表示栈满 , mCapacity - 1 表示栈顶
throw OutOfRangeError();
this->mData[++this->mIndex] = item;
return *this; // 返回当前对象,支持链式编程
}
T &at(int index) throw(OutOfRangeError)
{
// mIndex == -1 表示栈为空index < 0 表示索引小于 0index > mIndex 表示索引大于栈顶
if (mIndex == -1 || index < 0 || index > mIndex)
throw OutOfRangeError();
return this->mData[index];
}
int size() const
{
return this->mIndex + 1;
}
};
int main()
{
Stack<int> s1(5);
s1.push(10).push(20).push(30);
for (int i = 0; i < s1.size(); i++)
cout << s1.at(i) << endl;
cout << "*** 弹出数据 ***" << endl;
// 清空数据
while (1)
{
try
{
cout << s1.pop() << endl;
}
catch (exception &e)
{
cout << "error: " << e.what() << endl;
break; // 异常处理: 跳出循环
}
}
cout << "*** 弹栈完成,重新打印 ***" << endl;
for (int i = 0; i < s1.size(); i++)
cout << s1.at(i) << endl;
return 0;
}

30
day8/d2.cpp Normal file
View File

@ -0,0 +1,30 @@
// 处理异常的语法
// 捕获基本数据类型的异常
#include <iostream>
using namespace std;
int div(int a, int b)
{
if (b == 0)
{
throw "除数不能为0"; // 抛出异常
}
return a / b;
}
int main()
{
cout << "-----aaaaa-----" << endl;
int ret = 0;
try // 捕获异常
{
ret = div(20, 0);
}
catch (const char *err) // 捕获异常
{
cout << "异常: " << err << endl; // 处理异常
}
cout << "ret = " << ret << endl;
return 0;
}

75
day8/d3.cpp Normal file
View File

@ -0,0 +1,75 @@
// throw 的限制
// 在使用 throw 抛出异常信息时,受到函数声明处的 throw() 声明的
// 可抛出异常类型的限制。
// 如: 函数内可以抛出任何异常
#include <iostream>
using namespace std;
class A
{
public:
int n;
public:
A(int n = 0) : n(n) {}
};
// throw() 声明表示不抛出任何异常
// throw(int, char, double, A) 表示可以抛出 int, char, double, A 类型的异常
void show(int x) throw(int, char, double, A)
{
switch (x)
{
case 1:
throw 0;
break;
case 2:
throw 'a';
break;
case 3:
throw "abc";
break;
case 4:
throw 1.25;
break;
case 5:
throw A(100); // 抛出自定义类的对象
break;
// default 可以不写,因为前面已经覆盖了所有情况
}
cout << "x = " << x << endl;
}
int main()
{
cout << "输入一个整数: ";
int x;
cin >> x;
try
{
show(x);
}
catch (const int &error)
{
cout << "捕获异常: " << error << endl;
}
catch (const char &error)
{
cout << "捕获异常: " << error << endl;
}
catch (const char *error)
{
cout << "捕获异常: " << error << endl;
}
catch (const double &error)
{
cout << "捕获异常: " << error << endl;
}
catch (const A &error)
{
cout << "捕获异常: " << error.n << endl;
}
return 0;
}

71
day8/d4.cpp Normal file
View File

@ -0,0 +1,71 @@
// 限制函数抛出异常
// throw() 声明表示不抛出任何异常
#include <iostream>
using namespace std;
class A
{
public:
int n;
public:
A(int n = 0) : n(n) {}
};
// throw() 声明表示不抛出任何异常
void show(int x) throw()
{
switch (x)
{
case 1:
throw 0;
break;
case 2:
throw 'a';
break;
case 3:
throw "abc";
break;
case 4:
throw 1.25;
break;
case 5:
throw A(100); // 抛出自定义类的对象
break;
// default 可以不写,因为前面已经覆盖了所有情况
}
cout << "x = " << x << endl;
}
int main()
{
cout << "输入一个整数: ";
int x;
cin >> x;
try
{
show(x);
}
catch (const int &error)
{
cout << "捕获异常: " << error << endl;
}
catch (const char &error)
{
cout << "捕获异常: " << error << endl;
}
catch (const char *error)
{
cout << "捕获异常: " << error << endl;
}
catch (const double &error)
{
cout << "捕获异常: " << error << endl;
}
catch (const A &error)
{
cout << "捕获异常: " << error.n << endl;
}
return 0;
}

29
day8/d5.cpp Normal file
View File

@ -0,0 +1,29 @@
// 栈解旋(unwinding):当抛出异常时,会调用所有对象的析构函数
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
};
int main()
{
try
{
A a1;
// 栈解旋(unwinding):当抛出异常时,会调用所有对象的析构函数
throw 0; // 抛出异常时,则会调用 a1 的析构函数
}
catch (...) // ... 表示其他异常,可以不写,写的话必须放在最后
{
cout << "异常被处理" << endl;
}
return 0;
}

45
day8/d6.cpp Normal file
View File

@ -0,0 +1,45 @@
// 异常接口声明
// 如: 结构体作为异常对象
#include <iostream>
#include <cstring>
using namespace std;
struct ERROR_S
{
string title; // 错误信息
int errnum; // 错误码
} error_1; // ERROR_S error_1; // error_1 是一个全局变量
void test1(int n) throw(ERROR_S, int)
{
if (n == 0)
{
error_1.title = "n 参数不能为 0";
error_1.errnum = 1;
throw error_1;
}
else if (n == 1)
{
throw 2;
}
cout << "n = " << n << endl;
}
int main()
{
try
{
test1(1);
}
catch (const ERROR_S &error)
{
cout << "捕获异常: " << error.title << endl;
cout << "错误码: " << error.errnum << endl;
}
catch (...)
{ // ... 表示其他异常
cout << "捕获其他异常" << endl;
}
return 0;
}

53
day8/d7.cpp Normal file
View File

@ -0,0 +1,53 @@
// 异常变量生命周期
// 如 1: 抛出对象,接收对象,会使用拷贝构造函数
// 异常变量生命周期
// 如 1: 抛出对象,接收引用,不会使用拷贝构造函数,会直接使用构造函数
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class Exception
{
private:
string msg;
public:
Exception()
{
this->msg = "";
cout << this << "Exception()" << endl;
}
Exception(const string &msg)
{
this->msg = msg;
cout << this << "Exception(const string &)" << endl;
}
Exception(const Exception &other)
{
this->msg = other.msg;
cout << this << "Exception(const Exception &)" << endl;
}
~Exception() { cout << this << "~Exception()" << endl; }
public:
string &getMsg() // const 表示该成员函数不会修改成员变量
{
return this->msg;
}
};
int main()
{
try
{
throw Exception("异常");
}
catch (Exception e)
{
cout << "捕获异常: " << e.getMsg() << endl;
}
return 0;
}

51
day8/d8.cpp Normal file
View File

@ -0,0 +1,51 @@
// 异常变量生命周期
// 如 1: 抛出对象,接收引用,不会使用拷贝构造函数,会直接使用构造函数
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class Exception
{
private:
string msg;
public:
Exception()
{
this->msg = "";
cout << this << "Exception()" << endl;
}
Exception(const string &msg)
{
this->msg = msg;
cout << this << "Exception(const string &)" << endl;
}
Exception(const Exception &other)
{
this->msg = other.msg;
cout << this << "Exception(const Exception &)" << endl;
}
~Exception() { cout << this << "~Exception()" << endl; }
public:
string &getMsg() // const 表示该成员函数不会修改成员变量
{
return this->msg;
}
};
int main()
{
try
{
throw Exception("异常");
}
catch (Exception &e)
{
cout << "捕获异常: " << e.getMsg() << endl;
}
return 0;
}

53
day8/d9.cpp Normal file
View File

@ -0,0 +1,53 @@
// 异常变量生命周期
// 如 1: 抛出对象(堆区),捕获对象(堆区),会使用拷贝构造函数,需要手动释放内存
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
class Exception
{
private:
string msg;
public:
Exception()
{
this->msg = "";
cout << this << "Exception()" << endl;
}
Exception(const string &msg)
{
this->msg = msg;
cout << this << "Exception(const string &)" << endl;
}
Exception(const Exception &other)
{
this->msg = other.msg;
cout << this << "Exception(const Exception &)" << endl;
}
~Exception() { cout << this << "~Exception()" << endl; }
public:
string &getMsg() // const 表示该成员函数不会修改成员变量
{
return this->msg;
}
};
int main()
{
try
{
// 要使用 new 创建对象,否则会在栈区创建对象,导致异常抛出时,会调用析构函数
throw new Exception("异常"); // 在堆区创建对象
}
catch (Exception *e)
{
cout << "捕获异常: " << e->getMsg() << endl;
delete e; // 手动释放内存
}
return 0;
}

27
day8/stl_code/d1.cpp Normal file
View File

@ -0,0 +1,27 @@
// stl 标准模板库开发
// 初次使用:
// vector 存放基础类型的数据示例
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
// 创建迭代器
vector<int>::iterator it;
for (it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
return 0;
}

46
day8/stl_code/d2.cpp Normal file
View File

@ -0,0 +1,46 @@
// 存放类对象的数据 vector
#include <bits/stdc++.h>
using namespace std;
class Student
{
friend ostream &operator<<(ostream &out, const Student &stu);
private:
string name;
int age;
public:
Student(const string &name, int age)
{
this->name = name;
this->age = age;
}
};
ostream &operator<<(ostream &out, const Student &stu)
{
out << "name: " << stu.name << ", age: " << stu.age;
return out;
}
int main()
{
vector<Student> v;
v.push_back(Student("zhangsan", 20));
v.push_back(Student("lisi", 21));
v.push_back(Student("wangwu", 22));
v.push_back(Student("zhaoliu", 23));
v.pop_back(); // 删除最后一个元素
// 创建迭代器
vector<Student>::iterator it = v.end();
while (it != v.begin())
{
cout << *(--it) << endl; // 重载了<<运算符
}
return 0;
}

48
day8/stl_code/d3.cpp Normal file
View File

@ -0,0 +1,48 @@
// 基于 d3.cpp 的改进
// vector 存放对象的指针
#include <bits/stdc++.h>
using namespace std;
class Student
{
friend ostream &operator<<(ostream &out, const Student *stu);
private:
string name;
int age;
public:
Student(const string &name, int age)
{
this->name = name;
this->age = age;
}
};
ostream &operator<<(ostream &out, const Student *stu)
{
out << "name: " << stu->name << ", age: " << stu->age;
return out;
}
int main()
{
vector<Student *> v;
v.push_back(new Student("张三", 18));
v.push_back(new Student("李四", 19));
v.push_back(new Student("王五", 20));
v.pop_back(); // 删除最后一个元素
// 创建迭代器
vector<Student *>::iterator it = v.end();
while (it != v.begin())
{
it--;
cout << *it << endl; // 重载了<<运算符
delete *it; // 释放空间
}
return 0;
}

View File

@ -5,6 +5,7 @@ using namespace std;
int main() int main()
{ {
// 注意: vector<vector<int> > vs; 防止编辑器自动格式化为 >>
vector<vector<int> > vs; // 嵌套容器 vector<vector<int> > vs; // 嵌套容器
vector<int> v1, v2, v3; vector<int> v1, v2, v3;