在 C++11 中使用没有托管共享指针的shared_from_this()

2023-12-19

假设我有一个类,它是enable_shared_from_this 的子类。这个基类的文档说在调用shared_from_this之前应该有一个拥有这个类的共享指针。用new分配类并调用shared_from_this来管理对象是否安全?


正如其他用户已经提到的,调用shared_from_this在不属于的实例上shared_ptrs 将导致未定义的行为(通常是异常,但不能保证)。

那么,为什么还要多一个答案呢?

因为我自己也做过一次同样的问题,得到了几乎相同的答案,然后我开始为紧接着出现的另一个问题苦苦挣扎——我怎样才能保证所有实例都由一个管理shared_ptr?

为了完整起见,我添加了另一个答案,其中包含有关这方面的一些细节。
这是一个以前没有提到过的简单解决方案。

确实如此简单的解决方案:私有构造函数, 工厂方法 and 可变参数模板s.
它遵循一个片段,在一个最小的示例中将所有这些内容混合在一起:

#include<memory>
#include<utility>

class C: public std::enable_shared_from_this<C> {
    C() = default;
    C(const C &) = default;
    C(C &&) = default;
    C& operator=(const C &) = default;
    C& operator=(C &&c) = default;

public:
    template<typename... Args>
    static std::shared_ptr<C> create(Args&&... args) noexcept {
        return std::shared_ptr<C>{new C{std::forward<Args>(args)...}};
    }

    std::shared_ptr<C> ptr() noexcept {
        return shared_from_this();
    }
};

int main() {
    std::shared_ptr<C> c1 = C::create();
    std::shared_ptr<C> c2 = C::create(*c1);
    std::shared_ptr<C> c3 = c2->ptr();
    // these won't work anymore...
    // C c4{};
    // std::shared_ptr<C> c5 = std::make_shared<C>();
    // std::shared_ptr<C> c6{new C{}};
    // C c7{*c1};
    // ... and so on ...
}

基本(微不足道?)的想法是禁止显式构造新实例,但通过使用此处称为的工厂方法create.
可变参数模板用于避免编写多个工厂方法,仅此而已。完美转发帮助我们以正确的方式做到这一点。

很简单,不是吗?
不管怎样,我花了一段时间才弄清楚这一点,所以我希望这能帮助未来遇到同样疑问的读者。

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

在 C++11 中使用没有托管共享指针的shared_from_this() 的相关文章

  • ROWNUM 的 OracleType 是什么

    我试图参数化所有现有的 sql 但以下代码给了我一个问题 command CommandText String Format SELECT FROM 0 WHERE ROWNUM lt maxRecords command CommandT
  • Func 方法参数的首选命名约定是什么?

    我承认这个问题是主观的 但我对社区的观点感兴趣 我有一个缓存类 它采用类型的缓存加载器函数Func
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • Cygwin 下使用 CMake 编译库

    我一直在尝试使用 CMake 来编译 TinyXML 作为一种迷你项目 尝试学习 CMake 作为补充 我试图将其编译成动态库并自行安装 以便它可以工作 到目前为止 我已经设法编译和安装它 但它编译成 dll 和 dll a 让它工作的唯一
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • c 中的错误:声明隐藏了全局范围内的变量

    当我尝试编译以下代码时 我收到此错误消息 错误 声明隐藏了全局范围内的变量 无效迭代器 节点 根 我不明白我到底在哪里隐藏或隐藏了之前声明的全局变量 我怎样才能解决这个问题 typedef node typedef struct node
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 如何在 C# 中播放在线资源中的 .mp3 文件?

    我的问题与此非常相似question https stackoverflow com questions 7556672 mp3 play from stream on c sharp 我有音乐网址 网址如http site com aud
  • 将 viewbag 从操作控制器传递到部分视图

    我有一个带有部分视图的 mvc 视图 控制器中有一个 ActionResult 方法 它将返回 PartialView 因此 我需要将 ViewBag 数据从 ActionResult 方法传递到 Partial View 这是我的控制器
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐

  • 为什么 x86 汇编中的第一个参数从偏移量 8 开始?

    我正在努力加深对汇编语言的理解 我知道当函数创建堆栈帧时 它会推送当前的EBP 然后将堆栈指针值复制到EBP 第一个 也是唯一的 函数参数通过以下方式访问EBP 8 但为什么是8 推送后的下一个值EBP逻辑上偏移4 我读了很多网页 但似乎我
  • 有没有办法让StringIO读取阻塞

    我已经搜索了文档并四处搜索 但没有提到阻止 StringIO 对象 我可以创建我自己的类似文件的对象 它只是简单地包装 StringIO 但是使它阻塞的最佳方法是什么 我知道的唯一方法是使用 while 循环和 time sleep 0 1
  • 如何使用c程序查找我的机器是16位、32位还是64位

    有人可以给出简单的c程序来确定我的机器是16位 32位还是64位吗 如果您只关心 Linux 操作系统 那么您可以使用 uname 调用 您可以将 struct utsname 传递给此 API 并获取详细信息 您可以通过以下网址获取更多详
  • PHP foreach循环每2个项目包装一次

    div class puffar div
  • OpenCV无法绘制关键点

    我尝试运行所示的示例代码ORB in the openCV页 首先我必须弄清楚问题cv2 ORB 变成cv2 ORB create 出现此错误后 出现以下内容 Traceback most recent call last File orb
  • 将自定义信息添加到 HockeyApp 崩溃报告中

    我将我的 iOS 应用程序与 HockeyApp 平台集成 一切正常 但我需要添加一些额外的信息 例如来自 NSLog 的文本 以崩溃报告 有可能的 我不想使用外部框架 NSLogger CocoaLumberjack 数据库 服务器 We
  • js动态访问私有字段(属性/成员)

    我正在尝试新的类私有成员特征 https developer mozilla org en US docs Web JavaScript Reference Classes Class fields Private fields 然而 我很
  • EF4 可以为我生成 POCO,还是我必须自己编写它们?

    我最近一直在研究 Entity 4 框架 它非常漂亮 我已经设置了一个名为 Customer cs 的类 其中包含一些属性 例如名称 地址等 我还有一个名为 StoreEntities cs 的类 它通过 DbSet 将这些属性绑定回数据库
  • Python排序——对象列表

    如果可能的话 我想使用 somelist sort 方法来执行此操作 我有一个包含对象的列表 所有对象都有一个成员变量 resultType 它是一个整数 我想使用这个数字对列表进行排序 我该怎么做呢 Thanks somelist sor
  • 使用 MVVM 选择 ListView 中的所有项目

    我正在尝试选择所有Items in a ListView 使用 mvvm 使用代码隐藏 我尝试过全选 and foreach选择它们 但我想像项目的其余部分一样使用 MVVM 有任何想法吗 这是列表视图
  • 解析 request.object.existed() 返回 false

    我的解析有问题 我写了云代码 Parse Cloud afterSave Parse User function request var user request object if user existed all the times u
  • “git推送”和“git流放推送”有什么区别?

    我有一个 git 存储库 并且系统指示我执行以下操作序列 将给定的一组文件从文件夹复制到上述 git 存储库 源文件夹 不是存储库的一部分 Execute git add Execute git exile push folder name
  • 如何在反应日期中添加一年的选择?

    向右滑动几个月直到我到达正确的年份是很痛苦的react dates 是否有可能添加一些年份 月份的选择 是的 从版本开始是可能的 电子邮件受保护 cdn cgi l email protection 相关拉取请求 https github
  • gcc include 顺序损坏?

    我遇到了一个奇怪的问题 linux c 编译器包含本地目录而不是系统目录中的文件 使用 H 选项查看预编译器输出 可以看到系统文件 usr include sched h突然包括time h来自本地目录而不是系统一的标头 我假设如果包含文件
  • powershell 无法向 Excel 图表添加多个图例条目(系列)

    我在通过 powershell 将多个系列添加到 Excel 图表对象中的系列集合时遇到问题 这是我的代码 threading thread CurrentThread CurrentCulture en US excel New Obje
  • 带有 BroadcastReceiver 的清单中的 ACTION_USER_PRESENT

    对于是否可以通过清单捕获 ACTION USER PRESENT 屏幕解锁似乎存在不同意见 该线程暗示不 它不能完成 Android 广播接收器不工作 https stackoverflow com questions 6698716 an
  • 使用 Scala 中的原始类型实现 Java 接口

    我正在尝试使用 Scala 构建 Sonar 的扩展 我需要扩展以下 Java 接口 public interface Decorator extends BatchExtension CheckProject void decorate
  • 使用 NSKeyedUnarchiver 解码时出现问题

    我正在 XCode 3 2 3 上编写一个针对 iOS 4 0 的应用程序 当应用程序关闭时 我使用 NSCoder 协议存储一些数据 保存似乎工作正常 问题是从保存的文件中检索数据 我的保存方法如下所示 void saveMusicalW
  • 如何将 TrueType 字体转换为 PCL5 Soft 字体?

    如何将 TrueType 字体转换为 PCL5 softfont spf 主要思想是将软字体嵌入到 PCL5 打印文件中 然后选择它供打印机使用 因为它是通过 PCL5 命令指定的字体 ID 另外 如果您知道在创建 PCL5 文件时使用 T
  • 在 C++11 中使用没有托管共享指针的shared_from_this()

    假设我有一个类 它是enable shared from this 的子类 这个基类的文档说在调用shared from this之前应该有一个拥有这个类的共享指针 用new分配类并调用shared from this来管理对象是否安全 正