行业知识
知识点汇总2
文章目录
- weak_ptr
- 回调函数
- function包装器
- move
- 右值引用
- 多态
- 组合
- 自旋锁
- ���件描述符
weak_ptr
std::weak_ptr 是 std::shared_ptr 的一个伴随类,它允许你观察一个 std::shared_ptr 所管理的对象,但不会延长该对象的生命周期。换句话说,std::weak_ptr 不控制其指向对象的引用计数。它主要用于解决 std::shared_ptr 之间的循环引用问题,以避免内存泄漏。
()你不能使用 std::weak_ptr 来直接构造 std::shared_ptr 的原因主要有以下几点:
引用计数机制:std::shared_ptr 通过引用计数来管理对象的生命周期。当最后一个 std::shared_ptr 指向的对象被销毁或重置时,对象本身也会被销毁。而 std::weak_ptr 不参与引用计数,它仅仅观察 std::shared_ptr 的状态。如果允许用 std::weak_ptr 来构造 std::shared_ptr,那么就会破坏 std::shared_ptr 的引用计数机制,可能导致内存泄漏或其他未定义行为。
()所有权问题:std::shared_ptr 表示对对象的共享所有权,而 std::weak_ptr 不表示所有权。如果允许从 std::weak_ptr 构造 std::shared_ptr,那么就会引入所有权模糊的问题。这意味着你无法清晰地知道哪个 std::shared_ptr 实际“拥有”对象,这会导致代码维护和调试变得困难。
安全性问题:如果 std::weak_ptr 观察的 std::shared_ptr 已经被销毁(即其指向的对象不再存在),那么尝试从这样的 std::weak_ptr 构造 std::shared_ptr 是不安全的,因为这将导致悬垂指针(dangling pointer),访问这样的指针会导致未定义行为。
不过,虽然你不能直接用 std::weak_ptr 来构造 std::shared_ptr,但你可以使用 std::weak_ptr 的 lock 成员函数来尝试获取一个 std::shared_ptr。这个函数会尝试获取对对象的共享所有权。如果对象仍然存在(即至少还有一个 std::shared_ptr 指向它),那么 lock 会返回一个指向该对象的 std::shared_ptr;否则,它会返回一个空的 std::shared_ptr。这种方式既保证了安全性,又允许你在需要时获取对象的共享所有权。
示例代码:
std::shared_ptr shared = std::make_shared(42);std::weak_ptr weak = shared;// 尝试从weak_ptr获取shared_ptrstd::shared_ptr new_shared = weak.lock();if (new_shared) { // new_shared 现在有效,可以安全使用} else { // weak 观察的shared_ptr已经被销毁,new_shared 是空的}回调函数
在C++中,回调函数是一种通过函数指针或可调用对象(如函数对象、lambda表达式等)实现的机制,它允许一个函数(或可调用对象)作为参数传递给另一个函数,并在需要时由后者调用。回调函数在事件处理、异步编程、多线程、插件架构等场景中非常有用。
下面是一个简单的C++回调函数示例:
#include #include // 定义一个回调函数类型typedef std::function Callback;// 一个接受回调函数的函数void processData(int data, const Callback& callback) { // 对数据进行一些处理... std::cout std::cout // 将handleData作为回调函数传递给processData processData(10, handleData); // 使用lambda表达式作为回调函数 processData(20, [](int data) { std::cout return a + b;}int main() { // 使用std::function包装add函数 std::function1, 2, 3, 4, 5};// 创建另一个vector,并尝试通过移动vec1的内容来初始化它std::vector // x 是一个右值引用}