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;
}

posted @ 2021-04-24 12:44  AAAAAAAAA123123  阅读(36)  评论(0编辑  收藏  举报