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++ 维护子类对象的混合集合

    如果我在这里错过了一个相当基本的概念 我很抱歉 但我正在尝试弄清楚如何维护多个类类型的集合 所有类类型都派生自同一个父类 并且在检索它们时仍然可以访问它们的特定于子类的方法从集合中 作为上下文 我有一个基类 BaseClass 和许多类 例
  • 计算 XML 中特定 XML 节点的数量

    请参阅此 XML
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 为什么在 WebApi 上下文中在 using 块中使用 HttpClient 是错误的?

    那么 问题是为什么在 using 块中使用 HttpClient 是错误的 但在 WebApi 上下文中呢 我一直在读这篇文章不要阻止异步代码 https blog stephencleary com 2012 07 dont block
  • 当一组凭据下的计划任务启动的进程在另一组凭据下运行另一个程序时,Windows 是否有限制

    所以我有一个简单的例子 其中我有应用程序 A 它对用户 X 本地管理员 有一些硬编码的凭据 然后它使用硬编码的绝对路径启动带有这些凭据的应用程序 B A 和 B 以及 dotnet 控制台应用程序 但是它们不与控制台交互 只是将信息写入文件
  • C# 数据表更新多行

    我如何使用数据表进行多次更新 我找到了这个更新 1 行 http support microsoft com kb 307587 my code public void ExportCSV string SQLSyntax string L
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string

随机推荐