前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++-入门语法(六)

C++-入门语法(六)

作者头像
cwl_java
发布2019-10-28 10:23:41
2630
发布2019-10-28 10:23:41
举报
文章被收录于专栏:cwl_Javacwl_Java

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_42528266/article/details/102759289

const_cast
  • 一般用于去除const属性,将const转换成非const
dynamic_cast
  • 一般用于多态类型的转换,有运行时安全检测
static_cast
  • 对比dynamic_cast,缺乏运行时安全检测
  • 不能交叉转换(不是同一继承体系的,无法转换)
  • 常用于基本数据类型的转换、非const转成const
  • 使用范围较广
reinterpret_cast
  • 属于比较底层的强制转换,没有任何类型检查和格式转换,仅仅是简单的二进制数据拷贝
  • 可以交叉转换
  • 可以将指针和整数互相转换
C++标准的发展
在这里插入图片描述
在这里插入图片描述
C++11新特性
  • auto
    • 可以从初始化表达式中推断出变量的类型,大大简化编程工作
    • 属于编译器特性,不影响最终的机器码质量,不影响运行效率
  • decltype
    • 可以获取变量的类型
  • nullptr
    • 可以解决NULL的二义性问题
Lambda表达式
  • 有点类似于JavaScript中的闭包、iOS中的Block,本质就是函数
  • 完整结构: [capture list] (params list) mutable exception-> return type { function body }
    • capture list:捕获外部变量列表
    • params list:形参列表,不能使用默认参数,不能省略参数名
    • mutable:用来说用是否可以修改捕获的变量
    • exception:异常设定
    • return type:返回值类型
    • function body:函数体
  • 有时可以省略部分结构
    • [capture list] (params list) -> return type {function body}
    • [capture list] (params list) {function body}
    • [capture list] {function body}
C++14
  • 泛型Lambda表达式
  • 对捕获的变量进行初始化
C++17
在这里插入图片描述
在这里插入图片描述
  • 可以进行初始化的if、switch语句
代码语言:javascript
复制
#include <iostream>
using namespace std;

class Person {
public:
	int m_age;
};

void testAuto() {
	auto i = 10;
	auto name = "jack";
	auto d = 9.6;
	auto p = new Person();
	p->m_age = 10;
}

void func(int p) {
	cout << "func(int) - " << p << endl;
}

void func(int *p) {
	cout << "func(int *) - " << p << endl;
}

void test_nullptr() {
	/*int i = 10;
	const char *name = "jack";
	double d = 9.6;*/

	// int i = 0;
	// int *p = nullptr;

	/*func(0);
	func(NULL);
	func(nullptr);

	cout << (nullptr == NULL) << endl;*/

	int array[]{ 10, 20, 30, 40 };
	for (int item : array) {
		cout << item << endl;
	}

	/*int length = sizeof(array) / sizeof(int);
	for (int i = 0; i < length; i++)
	{
		cout << array[i] << endl;
	}*/
}

//int sum(int a, int b) { return a + b; }
//int minus1(int a, int b) { return a - b; }
//int multiple(int a, int b) { return a * b; }
//int divide(int a, int b) { return a / b; }

int exec(int a, int b, int (*func)(int, int)) {
	// ....
	// ...
	return func(a, b);
}

int main() {
	/*int (*p)(int, int) = [](int a, int b) -> int {
		return a + b;
	};

	cout << p(10, 20) << endl;*/

	/*cout << [](int a, int b) -> int {
		return a + b;
	}(10, 20) << endl;*/

	/*cout << [](int a, int b) {
		return a + b;
	}(10, 20) << endl;*/

	/*void(*p)() = [] {
		cout << 1 << endl;
		cout << 2 << endl;
		cout << 3 << endl;
	};
	p();
	p();*/

	/*cout << exec(20, 10, sum) << endl;
	cout << exec(20, 10, minus1) << endl;
	cout << exec(20, 10, multiple) << endl;
	cout << exec(20, 10, divide) << endl;*/

	/*cout << exec(20, 10, [](int a, int b) { return a + b; }) << endl;
	cout << exec(20, 10, [](int a, int b) { return a - b; }) << endl;
	cout << exec(20, 10, [](int a, int b) { return a * b; }) << endl;
	cout << exec(20, 10, [](int a, int b) { return a / b; }) << endl;*/


	//int a = 10;
	//int b = 20;

	//auto p = [a] () mutable {
	//	a++;
	//	cout << "lambda - " << a << endl;
	//};
	//p();

	//// 10
	//cout << a << endl;

	// 默认情况是值捕获
	/*auto p = [=, &a] {
		cout << a << endl;
		cout << b << endl;
	};

	a = 11;
	b = 22;

	p();*/


	
	if (int a = 10;  a > 5) {

	}
	else if (int b = 20; b > 10) {

	}
	else if (2) {

	}
	else {

	}


	

	getchar();
	return 0;
}
异常
  • 异常是一种在程序运行过程中的发生的不好预测的错误(比如内存不够)
  • 异常没有被处理,会导致程序终止
异常的抛出声明
  • 为了增强可读性和方便团队协作,如果函数内部可能会抛出异常,建议函数声明一下异常类型
标准异常(std)
在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
#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标准
代码语言:javascript
复制
#include <iostream>
using namespace std;

void test() {
	throw 6;
}

void test1() {
	try {
		int *p = new int();

		test();

		delete p;
	}
	catch (...) {
		cout << "出现异常" << endl;
	}
}

class Person {
public:
	Person() {
		cout << "Person()" << endl;
	}
	~Person() {
		cout << "~Person()" << endl;
	}

	void run() {
		cout << "Person::run()" << endl;
	}
};

void test2() {
	//cout << "1" << endl;
	//
	//{
	//	// Person *p = new Person();

	//	auto_ptr<Person> p(new Person());
	//	p->run();

	//}

	//cout << "2" << endl;
}

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
  • 当一个对象的强引用计数为0时(没有任何shared_ptr指向对象时),对象就会自动销毁(析构)
shared_ptr的注意点
  • 不要使用裸指针来初始化智能指针
  • 可以通过一个已存在的智能指针初始化一个新的智能指针
weak_ptr
  • weak_ptr会对一个对象产生弱引用,
  • weak_ptr可以指向对象解决shared_ptr的循环引用问题
unique_ptr
  • unique_ptr也会对一个对象产生强引用,它可以确保同一时间只有1个指针指向对象
  • 当unique_ptr销毁时(作用域结束时),其指向的对象也就自动销毁了
  • 可以使用std::move函数转移unique_ptr的所有权
代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • const_cast
  • dynamic_cast
  • static_cast
  • reinterpret_cast
  • C++标准的发展
  • C++11新特性
  • Lambda表达式
  • C++14
  • C++17
  • 异常
  • 异常的抛出声明
  • 标准异常(std)
  • 智能指针(Smart Pointer)
  • shared_ptr
  • shared_ptr的原理
  • shared_ptr的注意点
  • weak_ptr
  • unique_ptr
相关产品与服务
Prowork 团队协同
ProWork 团队协同(以下简称 ProWork )是便捷高效的协同平台,为团队中的不同角色提供支持。团队成员可以通过日历、清单来规划每⽇的工作,同时管理者也可以通过统计报表随时掌握团队状况。ProWork 摒弃了僵化的流程,通过灵活轻量的任务管理体系,满足不同团队的实际情况,目前 ProWork 所有功能均可免费使用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档