当我们创建一个std::shared_ptr,它会初始化引用计数为1,并创建一个控制块。当我们复制或赋值一个shared_ptr,它会指向同一个对象,并增加该对象控制块中的引用计数。当shared_ptr的实例被销毁或被重新赋值时,它会减少控制块中的引用计数。 如果引用计数变为零,意味着没有shared_ptr实例拥有该对象,此时会发生以下...
因为缺少解引用操作,没有办法写这样的代码。即使有,将检查和解引用分开会引入竞态条件:在调用expired和解引用操作之间,另一个线程可能对指向这对象的std::shared_ptr重新赋值或者析构,并由此造成对象已析构。这种情况下,你的解引用将会产生未定义行为。 你需要的是一个原子操作检查std::weak_ptr是否已经过期,如果没...
auto p = std::make_shared<Person>("Chris"); 表示创建了智能指针对象,对Person对象进行管理,该Person对象的构造函数的输入参数为字符串"Chris"。此时,可以使用auto自动推导。 1.3reset 就是让智能指针对象重新指向一个新的对象,而对原来所指对象的计数减1。 在进行reset(new xxx())重新赋值时,智能指针对象首先...
在某些情况下,reset可以避免动态内存分配。考虑一下代码
使用reset()时,传递给reset的参数不必是托管对象(也不能是);而使用=时,右侧必须是托管对象。
当一个std::shared_ptr指向某个资源时,该资源的引用计数会加1;当std::shared_ptr被销毁或重新赋值时,该资源的引用计数会减1。只有当引用计数变为0时,资源才会被释放。 这样,多个std::shared_ptr可以共享同一个资源,并且在合适的时候自动释放资源,避免了内存泄漏和资源泄漏的问题。但需要注意的是,引用计数机制无...
它们尺寸相同,都使用了控制块(见条款19),其构造,析构,赋值都涉及了对引用计数的原子操作。你可能会吃惊,因为我在本条款开始提到了std::weak_ptr不参与引用计数的操作。其实那不是我写的,我写的是std::weak_ptr不涉及对象的共享所有权,因此不影响对象的引用计数。实际山控制块里面有第二个引用计数,std::weak_...
如果使用移动构造函数或移动赋值运算符从另一个std::shared_ptr中移动资源(而不是复制),则不会增加引用计数。相反,源std::shared_ptr将被设置为nullptr,而新的std::shared_ptr将接管对资源的所有权。移动构造函数和移动赋值运算符使得std::shared_ptr能够更高效地转移所有权,因为它们避免了引用计数的增减操作。这...
即使能写出来,把解引用和检查分离开来会造成竞争条件:在调用expired和解引用操作中间,另外一个线程可能重新赋值或者销毁std::shared_ptr之前指向的对象,因此,会造成你想解引用的对象被销毁。这样的话,你的解引用操作将产生未定义行为。 你需要的是一个原子操作,它能检查看std::weak_ptr是否失效了,并让你能访问它...
即使又没法做到,将检查和解引用分开的写法也会引入一个竞态存在:在调用expired以及解引用操作之间,另外一个线程可能对被指向的对象重新赋值或者摧毁了最后一个指向对象的std::shared_ptr,这样就导致了被指向的对象的析构。这种情况下,你的解引用操作会产生未定义行为。