day20_异常
异常
◼ 异常是一种在程序运行过程中的发生的不好预测的错误(比如内存不够)
◼ 异常没有被处理,会导致程序终止
◼ throw异常后,会在当前函数中查找匹配的catch,找不到就 终止当前函数代码,去上一层函数中查找。如果最终都找不 到匹配的catch,整个程序就会终止
#include <iostream>
using namespace std;
//int sum(int a, int b) {
// // 业务逻辑写错了
// return a - b;
//}
void test() {
cout << "1" << endl;
// 如果内存不够,就会抛出异常(运行过程中抛出一个错误)
try {
for (int i = 0; i < 9999999; i++) {
int *p = new int[9999999];
}
cout << "2" << endl;
}
catch (...) {
cout << "发生了异常" << endl;
}
cout << "3" << endl;
// delete[] p;
}
void test(int a, int b, int c) {
if (a <= 0) return;
}
int divide(int a, int b) {
if (b == 0) throw "不能除以0";
return a / b;
}
void test2() {
cout << "1" << endl;
try {
int v1 = 10;
int v2 = 0;
cout << divide(v1, v2) << endl;
}
catch (int exception) {
cout << "捕捉到异常1:" << exception << endl;
}
catch (const char *exception) {
cout << "捕捉到异常2:" << exception << endl;
}
cout << "2" << endl;
}
void test3() {
try {
throw 3;
} catch (const char *exception) {
cout << "test3-捕捉到异常:" << exception << endl;
}
// 432432
// 4324234
// .....
}
void test4() {
try {
test3();
} catch (int exception) {
cout << "test4-捕捉到异常:" << exception << endl;
}
// .....
}
class Exception {
public:
virtual const char *what() const = 0;
};
class DivideException : public Exception {
public:
const char *what() const {
return "不能除以0";
}
};
class AddException : public Exception {
public:
const char *what() const {
return "加法有问题";
}
};
int divide2(int a, int b) {
if (b == 0) throw DivideException();
return a / b;
}
int main() {
/*try {
divide2(10, 0);
} catch (const DivideException &e) {
cout << e.what() << endl;
} catch (const AddException &e) {
}*/
try {
for (int i = 0; i < 9999999; i++) {
int *p = new int[9999999];
}
// 234234234
} catch (bad_alloc e) {
cout << e.what() << endl;
}
getchar();
return 0;
}
智能指针(Smart Pointer)
-
传统指针存在的问题
- 需要手动管理内存
- 容易发生内存泄露(忘记释放、出现异常等)
- 释放之后产生野指针
-
智能指针就是为了解决传统指针存在的问题
-
auto_ptr:属于C++98标准,在C++11中已经不推荐使用(有缺陷,比如不能用于数组)
-
shared_ptr:属于C++11标准
-
unique_ptr:属于C++11标准
智能指针的简单自实现
template <class T>
class SmartPointer {
T *m_pointer;
public:
SmartPointer(T *pointer) :m_pointer(pointer) { }
~SmartPointer() {
if (m_pointer == nullptr) return;
delete m_pointer;
}
T *operator->() {
return m_pointer;
}
};
int main() {
cout << "1" << endl;
{
SmartPointer<Person> p(new Person());
p->run();
}
cout << "2" << endl;
getchar();
return 0;
}
shared_ptr
shared_ptr的设计理念
多个shared_ptr可以指向同一个对象,当最后一个shared_ptr在作用域范围内结束时,对象才会被自动释放
shared_ptr的原理
◼一个shared_ptr会对一个对象产生强引用(strong reference)
◼ 每个对象都有个与之对应的强引用计数,记录着当前对象被多少个shared_ptr强引用着可以通过shared_ptr的use_count函数获得强引用计数
◼ 当有一个新的shared_ptr指向对象时,对象的强引用计数就会+1
◼ 当有一个shared_ptr销毁时(比如作用域结束),对象的强引用计数就会-1
shared_ptr的注意点
◼ 不要使用裸指针来初始化智能指针,比如以下代码
◼ 可以通过一个已存在的智能指针初始化一个新的智能指针
weak_ptr会对一个对象产生弱引用
weak_ptr可以指向对象解决shared_ptr的循环引用问题
unique_ptr
◼ unique_ptr也会对一个对象产生强引用,它可以确保同一时间只有1个指针指向对象
◼ 当unique_ptr销毁时(作用域结束时),其指向的对象也就自动销毁了
◼ 可以使用std::move函数转移unique_ptr的所有权
#include <iostream>
using namespace std;
class Person;
class Car {
public:
// Person *m_person;
// shared_ptr<Person> m_person = nullptr;
weak_ptr<Person> m_person;
Car() {
cout << "Car()" << endl;
}
~Car() {
cout << "~Car()" << endl;
}
};
class Person {
public:
// Car *m_car;
shared_ptr<Car> m_car = nullptr;
Person() {
cout << "Person()" << endl;
}
~Person() {
cout << "~Person()" << endl;
}
void run() {
cout << "Person::run()" << endl;
}
};
void test1() {
cout << "1" << endl;
{
shared_ptr<Person> p2;
{
shared_ptr<Person> p1(new Person());
p2 = p1;
cout << "2" << endl;
}
cout << "3" << endl;
}
cout << "4" << endl;
}
void test2() {
/*auto expr = [](Person *p) {
delete[] p;
};
shared_ptr<Person> p1(new Person[5]{}, expr);*/
shared_ptr<Person[]> p2(new Person[5]{});
}
void test3() {
{
shared_ptr<Person> p1(new Person());
cout << p1.use_count() << endl; // 1
{
shared_ptr<Person> p2 = p1;
cout << p1.use_count() << endl; // 2
}
cout << p1.use_count() << endl; // 1
{
shared_ptr<Person> p3 = p1;
cout << p1.use_count() << endl; // 2
}
cout << p1.use_count() << endl; // 1
shared_ptr<Person> p4 = p1;
cout << p1.use_count() << endl; // 2
} // 0
}
void test4() {
Person *p = new Person();
{
shared_ptr<Person> p1(p);
}
{
shared_ptr<Person> p2(p);
}
}
void test5() {
/*Person *p = new Person();
p->m_car = new Car();
p->m_car->m_person = p;*/
cout << "1" << endl;
{
shared_ptr<Person> person(new Person());
shared_ptr<Car> car(new Car());
person->m_car = car;
car->m_person = person;
}
cout << "2" << endl;
}
int main() {
{
unique_ptr<Person> p1(new Person());
{
unique_ptr<Person> p2 = std::move(p1);
cout << "1" << endl;
}
cout << "2" << endl;
}
getchar();
return 0;
}