欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > C++Cherno 学习笔记day18 [71]-[75] C++安全、PCH、dynamic_cast、基准测试、结构化绑定

C++Cherno 学习笔记day18 [71]-[75] C++安全、PCH、dynamic_cast、基准测试、结构化绑定

2025/5/6 21:46:12 来源:https://blog.csdn.net/Shirleyyy1/article/details/147080486  浏览:    关键词:C++Cherno 学习笔记day18 [71]-[75] C++安全、PCH、dynamic_cast、基准测试、结构化绑定

b站Cherno的课[71]-[75]

  • 一、现代C++中的安全以及如何教授
  • 二、C++的预编译头文件PCH
  • 三、C++的dynamic_cast
  • 四、C++的基准测试
  • 五、C++的结构化绑定

一、现代C++中的安全以及如何教授

安全编程,或者说C++编程中,降低崩溃,内存泄露、非法访问等问题
C++11,智能指针,而不是原始指针,想要分配堆内存

用于生产环境使用智能指针,用于学习和了解工作积累,使用原始指针,当然,如果你需要定制的话,也可以使用自己写的智能指针

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、C++的预编译头文件PCH

precompiled header(预编译头文件)

预编译的头文件实际上是让你抓取一堆头文件,并将它们转换成编译器可以使用的格式,而不必一遍又一遍地读取这些头文件

使用预编译头文件,可以加速编译时间,它们也使实际编写代码更加方便
因为你不需要一遍又一遍地去包含常用的头文件
尤其在持续集成(CI)和频繁构建的场景下效果更为明显

在这里插入图片描述

三、C++的dynamic_cast

dynamic casting 动态转换类型
C++风格的转换
只能在C++中用不能在C
更像是一个函数,它不像编译时进行的类型转换,而是在运行时计算

dynamic_cast 是一种用于在运行时安全执行向下转型(downcasting)或跨继承层次转型的运算符。它是C++运行时类型识别**(RTTI)机制的一部分,核心目的是确保类型转换的安全性**。

在这里插入图片描述

// 指针类型转换
Derived* pd = dynamic_cast<Derived*>(base_ptr);// 引用类型转换(失败时抛出异常)
Derived& rd = dynamic_cast<Derived&>(base_ref);

dynamic_cast 专门用于沿继承层次结构进行的强制类型转换

RTTI 运行时类型信息(runtime type information)
它存储我们的所有类型的运行时类型信息
增加开销,但它可以让你做动态类型转换之类的事情

在这里插入图片描述

#include <iostream>
#include <string>class Entity
{
};class Player :public Entity
{
};class Enemy :public Entity
{
};
int main()
{	Player* player = new Player();Entity* actuallyEnemy = new Enemy();Entity* actuallyEnemy = player;Player* p0 = dynamic_cast<Player*>(actuallyEnemy);Player* p1 = dynamic_cast<Player*>(actuallyPlayer);std::cin.get();
}

在这里插入图片描述
关闭后出现警告:dynamic cast’ used on polymorphic type Entity with /
GR-,/GR-的意思是我们关掉了RTTI,给我们带来不可预测的行为

dynamic_cast 是C++中实现安全类型转换的关键工具,但其使用应遵循以下原则:

必要性:仅在必须进行运行时类型检查时使用

安全性:始终检查转换结果(指针)或捕获异常(引用)

设计优先:优先通过多态和良好的类设计减少类型转换需求

四、C++的基准测试

#include <iostream>
#include <memory>int main()
{	int value = 0;for (int i = 0; i < 1000000; i++)value += 2;std::cout << value << std::endl;__debugbreak();
}

在这里插入图片描述

#include <iostream>
#include <memory>#include <chrono>
#include <array>class Timer
{
public:Timer(){m_StartTimepoint = std::_NO_SUCH_PROCESS::high_resolution_clock::now();}~Timer(){Stop();}void Stop(){auto endTimepoint = std::chrono::high_resolution_clock::now();auto start = std::chrono::time_point_cast<std::chrono::microseconds>(m_StartTimepoint).time_since_epoch().count();auto stop = std::chrono::time_point_cast<std::chrono::microseconds>(endTmiepoint).time_since_epoch().count();auto duration = end - start;double ms = duration * 0.001;std::cout << duration << "us (" << ms << "ms )\n";}private:std::chrono::time_point< std::chrono::high_resolution_clock> m_StartTimepoint;
};int main()
{	int value = 0;{Timer timer;for (int i = 0; i < 1000000; i++)value += 2;}std::cout << value << std::endl;__debugbreak();
}

在这里插入图片描述

#include <iostream>
#include <memory>#include <chrono>
#include <array>class Timer
{
public:Timer(){m_StartTimepoint = std::_NO_SUCH_PROCESS::high_resolution_clock::now();}~Timer(){Stop();}void Stop(){auto endTimepoint = std::chrono::high_resolution_clock::now();auto start = std::chrono::time_point_cast<std::chrono::microseconds>(m_StartTimepoint).time_since_epoch().count();auto stop = std::chrono::time_point_cast<std::chrono::microseconds>(endTmiepoint).time_since_epoch().count();auto duration = end - start;double ms = duration * 0.001;std::cout << duration << "us (" << ms << "ms )\n";}private:std::chrono::time_point< std::chrono::high_resolution_clock> m_StartTimepoint;
};int main()
{	struct Vector2{float x, y;};std::cout << "Make Shared\n";{std::array<std::shared_pr<Vector2>,1000> sharedPtrs;Timer timer;for (int i = 0; i < sharedPtrs.size(); i++)sharedPtrs[i] = std::make_shared<Vector2>();}std::cout << "New Shared\n";{std::array<std::shared_pr<Vector2>,1000> sharedPtrs;Timer timer;for (int i = 0; i < sharedPtrs.size(); i++)sharedPtrs[i] = std::shared_ptr<Vector2>(new Vector2());}std::cout << "Make Unique\n";{std::array<std::unique_pr<Vector2>, 1000> sharedPtrs;Timer timer;for (int i = 0; i < sharedPtrs.size(); i++)sharedPtrs[i] = std::make_unique<Vector2>();}__debugbreak();
}

在这里插入图片描述

五、C++的结构化绑定

Istructured bindings(结构化绑定)
只针对C++17

结构化绑定是一个新特性,让我们更好的处理多返回值

在C++17中,结构化绑定(Structured Bindings) 是一种简化多变量初始化的语法,允许将数组、结构体或元组等复合类型的成员直接绑定到独立的变量上,提升代码可读性和简洁性。

auto [var1, var2, ..., varN] = expression;  // 值拷贝
auto& [var1, var2, ..., varN] = expression; // 引用绑定

在这里插入图片描述

#include <iostream>
#include <string>
#include <tuple>std::tuple<std::string, int> CreatePerson()
{return { "Cherno", 24 };
}int main()
{std::string name;int age;std::tie(name, age) = CreatePerson();
}

实际上一个结构体来给要返回的参数组命名有助于提升代码可读性,而且还可以方便的处理重名问题

通过结构化绑定,C++代码可以更直观地处理复合数据,减少冗余变量声明,同时保持类型安全和性能。它是现代C++中提升代码简洁性的重要工具之一。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词