C++11智能指针(unique_ptr、shared_ptr、weak_ptr)boost::scoped_ptr

2023-11-18

C++11智能指针(unique_ptr、shared_ptr、weak_ptr)_~码农小非~的专栏-CSDN博客_c++ shared_ptr weak_ptr

原创)智能指针拾遗

(原创)智能指针拾遗 - qicosmos(江南) - 博客园

shared_ptr的 reset用法 - tycoon3 - 博客园 (cnblogs.com)

手写智能指针(类)_L_smartworld的博客-CSDN博客_手写智能指针

c++智能指针出现后是不是就可以不用new和delete了?

c++智能指针出现后是不是就可以不用new和delete了? - 知乎

c++11 智能指针 unique_ptr、shared_ptr与weak_ptr

c++11 智能指针 unique_ptr、shared_ptr与weak_ptr - lsgxeva - 博客园

(717条消息) c++11特性(六)智能指针_智能指针赋值_钢钢钢很不爽的博客-CSDN博客

(680条消息) 避免使用c/c++指针引发的问题_c++如何防止函数结束释放_饮风而醉的博客-CSDN博客

(699条消息) 从源码理解智能指针(二)—— shared_ptr、weak_ptr_HerofH_的博客-CSDN博客

为什么多线程读写 shared_ptr 要加锁?_xuhao_xuhao的专栏-程序员ITS304 - 程序员ITS304

C++11中智能指针的原理、使用、实现

C++11中智能指针的原理、使用、实现 - wxquare - 博客园

c++智能指针——原理与实现

c++智能指针——原理与实现_runner668的博客-CSDN博客_c++智能指针

因为智能指针用到计数器,为了提升性能(实际影响微不足道)要尽量减少临时智能指针变量的产生,尽量用引用或左值引用,用std::move捕捉右值。

shared_ptr的线程安全性_DXT的博客-CSDN博客_shared_ptr线程安全

shared_ptr的reference count是线程安全的,但是指向的对象不是线程安全的!

(689条消息) [c++] 智能指针shared_ptr_shared_ptr获取值_wabil的博客-CSDN博客

//Demo1.cc
 
#include <iostream>
#include<memory>
 
using namespace std;
 
int main()
{
 int a = 120;
 
 shared_ptr<int>  pt  =  make_shared<int>(a);
    //连续make_shared会把上一次的自动析构掉,释放掉
  pt = make_shared<int>(50);
 
  int *pRaw = pt.get();
 
   cout<< "rawValue="<<*pRaw<<endl; //you will see =120 
  return 0;
}
 
//MakeFile:  g++ Demo1.cc ;./a.out

    //连续make_shared 一个指针  会把上一次的自动析构掉,释放掉

关于c ++:std :: shared_ptr-将共享指针作为参数传递的最佳实践 | 码农家园 (codenong.com)

class ServiceB {
public:
    ServiceB() {}
};

class ServiceA {
public:
    ServiceA(std::shared_ptr<ServiceB>& serviceB)
        : _serviceB(serviceB) {

    }

private:
    std::shared_ptr<ServiceB> _serviceB;
};

class Root {
public:
    Root()
        : _serviceB(std::shared_ptr<ServiceB>(new ServiceB())),
        _serviceA(std::unique_ptr<ServiceA>(new ServiceA(_serviceB))) {

    }

private:
    std::shared_ptr<ServiceB> _serviceB;
    std::unique_ptr<ServiceA> _serviceA;
};

shared_ptr使用场景、陷阱、性能分析,使用建议

shared_ptr使用场景、陷阱、性能分析,使用建议_INGNIGHT的专栏-CSDN博客_shared_ptr使用场景

C++11使用make_shared的优势和劣势

C++11使用make_shared的优势和劣势 - 南哥的天下 - 博客园

C++ 原始指针、shared_ptr、unique_ptr分别在什么场景下使用

C++ 原始指针、shared_ptr、unique_ptr分别在什么场景下使用_知乎:C加加辅导袁老师的博客-CSDN博客

-22 增加了unique_ptr指针的使用

1 智能指针天生负责对象生命期管理;所以生命期对象全都由unique_ptr和shared_ptr来管理。

2 原始指针天生不负责对象生命周期管理,这时候使用shared_ptr来传递动态对象和使用原始指针来传递动态对象本质上没有区别,为了简单还是传递原始指针更好一些。

下面是示例代码:

class T3;
class T2;
class T1;
 
class A
{
    T3* m_t2;//创建和释放都由A之外的代码管理,A只负责(借用)使用;业务逻辑上保证A在使用m_t2指向的对象的时候,对象始终是存在的
    shared_ptr<T2> m_t2;//由加载程序创建m_t2指向的对象,执行时,交给A来管理,涉及动态对象的管理权的交接
    unique_ptr<T1> m_t1;//A管理该对象的生命周期,A的构造函数构造m_t1, A的析构函数释放m_t1;
};
 

很多人怕写C/C++ 程序就是因为指针,因为指针给了程序员高度的自由,同样也赋予了高度的责任,稍有不慎就导致内存泄漏。其实写C++ 可以完全不用指针,尤其C++ 11对智能指针作了进一步的升级,在不需要使用任何裸指针的前提下也可以写出高效的C++ 程序。C++ 11中定义了unique_ptrshared_ptrweak_ptr三种智能指针(smart pointer),都包含在<memory>头文件中。智能指针可以对动态分配的资源进行管理,保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。

shared_ptr

shared_ptr允许多个该智能指针共享“拥有”同一堆分配对象的内存,这通过引用计数(reference counting)实现,会记录有多少个shared_ptr共同指向一个对象,一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。支持复制和赋值操作。

weak_ptr

weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作,它可以从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用计数的增加或减少。没有重载 *和 -> 但可以使用lock获得一个可用的shared_ptr对象

weak_ptr的使用更为复杂一点,它可以指向shared_ptr指针指向的对象内存,却并不拥有该内存,而使用weak_ptr成员lock,则可返回其指向内存的一个share_ptr对象,且在所指对象内存已经无效时,返回指针空值nullptr。

注意:weak_ptr并不拥有资源的所有权,所以不能直接使用资源。 可以从一个weak_ptr构造一个shared_ptr以取得共享资源的所有权。

  asyncTask([media_stream] (std::shared_ptr<WebRtcConnection> connection) {
    boost::mutex::scoped_lock lock(connection->update_state_mutex_);
    ELOG_DEBUG("%s message: Adding mediaStream, id: %s", connection->toLog(), media_stream->getId().c_str());
    connection->media_streams_.push_back(media_stream);
  });


void WebRtcConnection::asyncTask(std::function<void(std::shared_ptr<WebRtcConnection>)> f) {
  std::weak_ptr<WebRtcConnection> weak_this = shared_from_this();
  worker_->task([weak_this, f] {
    if (auto this_ptr = weak_this.lock()) {
      f(this_ptr);  //this_ptr = std::shared_ptr<erizo::WebRtcConnection> 
    }
  });
}

weak_ptr
weak_ptr是为了配合shared_ptr而引入的一种智能指针,因为它不具有普通指针的行为,没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。使用weak_ptr的成员函数use_count()可以观测资源的引用计数,另一个成员函数expired()的功能等价于use_count()==0,但更快,表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在。weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象, 从而操作资源。但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr
 

(699条消息) C++11 新特性_c++ expired_t0tott的博客-CSDN博客

std::unique_ptr用法

如名字所示,unique_ptr是个独占指针,C++ 11之前就已经存在,unique_ptr所指的内存为自己独有,某个时刻只能有一个unique_ptr指向一个给定的对象,不支持拷贝和赋值。下面以代码样例来说明unique_ptr的用法,各种情况都在代码注释给出。

std::unique_ptr用法 - 简书

一、原则

使用std::unique_ptr管理具备专属所有权的资源

二、常见用法

std::unique_ptr的一个常见用法是在对象继承谱系中作为工厂函数的返回型别。这种继承谱系的工厂函数通常会在堆上分配一个对象并且返回一个指涉到它的指针,并当不在需要该对象时,由调用者负责删除之。

重置 unique_ptr 对象

C++ 智能指针 unique_ptr 详解与示例_彼此当年少,莫负好时光-CSDN博客_c++ unique_ptr

taskPtr.reset();

在 unique_ptr 对象上调用reset()函数将重置它,即它将释放delete关联的原始指针并使unique_ptr 对象为空。

C++ 智能指针 unique_ptr 详解与示例_彼此当年少,莫负好时光-CSDN博客_c++ unique_ptr

unique_ptr 是 C++ 11 提供的用于防止内存泄漏的智能指针中的一种实现,独享被管理对象指针所有权的智能指针。unique_ptr对象包装一个原始指针,并负责其生命周期。当该对象被销毁时,会在其析构函数中删除关联的原始指针。
unique_ptr具有->和*运算符重载符,因此它可以像普通指针一样使用。
查看下面的示例:

std::unique_ptr<PayloadDescriptor> payloadDescriptor(new PayloadDescriptor());

三、示例(以下代码需要c++14支持

#ifndef UNIQUEPTRDEMO_H
#define UNIQUEPTRDEMO_H

#include <iostream>
#include <memory>

namespace T17_NS {

using namespace std;

/*!
 * \brief The Investment class 基类
 */
class Investment
{
public:
    virtual ~Investment() = default;

public:
    virtual void doWork() = 0;
};

/*!
 * \brief The Stock class 派生类
 */
class Stock : public Investment
{
public:
    virtual void doWork() override {
        cout << "Stock doWork....\n";
    }
};

/*!
 * \brief The Stock class 派生类
 */
class Bond : public Investment
{
public:
    virtual void doWork() override {
        cout << "Bond doWork....\n";
    }
};

enum class InvestType {
    INVEST_TYPE_STOCK,
    INVEST_TYPE_BOND,
};

auto makeInvestment(InvestType type)
{
    // 自定义析构器, 这里以lambda表达式的形式给出
    auto delInvmt = [](Investment *pInvestment) {
        // TODO 自定义析构时想干的事
        cout << "delInvmt called...." << endl;
        delete pInvestment;
    };

    // 待返回的指针, 初始化为空指针,并指定自定义析构器
    // decltype(delInvmt) 用于获取自定义析构器的类型
    unique_ptr<Investment, decltype(delInvmt)> pInv(nullptr, delInvmt);

    // 注意这里用reset来指定pInv获取从new产生的对象的所有权, 不能用=赋值
    switch (type)
    {
    case InvestType::INVEST_TYPE_STOCK:
        //pInv = new Stock; // error!! c++11禁止从裸指针到智能指针的隐式转换
        pInv.reset(new Stock);
        break;
    case InvestType::INVEST_TYPE_BOND:
        pInv.reset(new Bond);
        break;
    }

    // 返回智能指针
    return pInv;
}

void test()
{
    // 测试工厂函数
    {
        // pInv出作用域后会自己析构
        auto pInv = makeInvestment(InvestType::INVEST_TYPE_STOCK);
        if (pInv)
        {
            pInv->doWork();
        }
    }

    cout << "----------------\n";

    // 测试move效果
    {
        auto pInv = makeInvestment(InvestType::INVEST_TYPE_BOND);
        auto pInv2 = move(pInv);
        cout << "after move pInv to pInv2 \n";
        if (!pInv)
        {
            cout << "pInv is empty \n";
        }
        if (pInv2)
        {
            cout << "pInv2 is valid \n";
            pInv2->doWork();
        }
    }

    cout << "----------------\n";

    // 测试unique_ptr向shared_ptr转换
    {
        shared_ptr<Investment> pInv = makeInvestment(InvestType::INVEST_TYPE_BOND);
        pInv->doWork();
    }
}

} // T17_NS

#endif // UNIQUEPTRDEMO_H


为什么 C++ Primer 5 上说shared_ptr的use_count()操作可能很慢?

为什么 C++ Primer 5 上说shared_ptr的use_count()操作可能很慢? - 知乎

unique_ptr.reset()  重置指针

unique_ptr::reset - C++ Reference

智能指针是比raw 指针更智能的类,解决 dangling指针或多次删除被指向对象,以及资源泄露问题,通常用来确保指针的寿命和其指向对象的寿命一致。智能指针虽然很智能,但容易被误用,智能也是有代价的。
通常有两大类型的智能指针:独占式unique_ptr和共享式shared_ptr。这两者的区别和使用场景,更适合使用unique_ptr的场景:1.语义简单,即当你不确定使用的指针是不是被分享所有权的时候,默认选unique_ptr独占式所有权,当确定要被分享的时候可以转换成shared_ptr;2.unique_ptr效率比shared_ptr高,不需要维护引用计数和背后的控制块;3.unique_ptr用起来更顺畅,选择性更多,可以转换成shared_ptr和通过get和release定制化智能指针(custom smart pointer)。
 

boost::scoped_ptr<webrtc::RtpRtcp> m_rtpRtcp;

boost::scoped_ptr是一个比较简单的智能指针,它能保证在离开作用域之后它所管理对象能被自动释放。下面这个例子将介绍它的使用:

{

boost::scoped_ptr<Book> myBook(new Book());

}

[C++] Boost智能指针——boost::shared_ptr(使用及原理分析

[C++] Boost智能指针——boost::shared_ptr(使用及原理分析)_dxmcu的专栏-CSDN博客_boost::shared_ptr reset

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11智能指针(unique_ptr、shared_ptr、weak_ptr)boost::scoped_ptr 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 按成员序列化

    我已经实现了template
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co

随机推荐