【问题标题】:Smart pointer with allocation on first access首次访问时分配的智能指针
【发布时间】:2020-02-26 16:37:54
【问题描述】:

TL;DR: 是否有一个类似于std::unique_ptr 的智能指针类的实现,它只实例化封装的对象并在指针第一次取消引用时分配内存?

背景:

我们有一个Process 类代表一个正在运行的进程。当进程执行网络通信时,我们会记录该活动并将其存储在 NetworkActivity 类对象中,该对象是 Process 类的成员。

NetworkActivity 是一个有很多成员变量的大类。我正在尝试减少内存使用并仅为一小部分进程实例化 NetworkActivity 对象,这些进程实际上通过网络进行通信。

当然,我可以在 Process 类中使用 unique_ptr:

std::unique_ptr<NetworkActivity> networkActivityPtr;

但是每次我取消引用它时,我都需要检查networkActivityPtr 是否有nullptr。如果我忘记了这样的检查并且还没有分配内存,程序就会崩溃。

第一次取消引用智能指针时,是否没有构造对象的unique_ptr 变体?

【问题讨论】:

  • 不,C++ 中没有标准的惰性初始化智能指针。也许您可以使用一个函数来执行检查并返回指针。
  • 您可以将检查 null 并在访问器中实例化
  • 看起来你有 XY 问题,创建一个返回对 NetworkActivity 的引用的方法,并在其他任何地方使用它。在该方法中检查指针并在必要时进行初始化。
  • 拥有一个像这样延迟初始化的类会产生额外的开销,因为每次访问都会检查 nullptr,并可能允许错误通过而未被检测到(因为访问其中一个空的会创建可能不是预期的行为)。追踪所有潜在的首次访问位置并检查是否需要创建对象应该相当容易(如果乏味的话)。

标签: c++ c++14 smart-pointers


【解决方案1】:

答案是否定的。看到这个:Dr. Dobbs article。您需要编写自己的包装器。

但是,当您的进程第一次启动时,它的初始化代码会创建实例。

【讨论】:

    【解决方案2】:

    出于线程安全的目的,您真正想要的是future&lt;NetworkActivity&gt; 之类的东西。这清楚地区分了访问指针值的行为(它是轻量级且微不足道的,以使线程安全)和创建对象(这是重量级的,需要线程同步以使线程安全) .没有人期望future::get 很快(如果值已经可用,它可能会很快,但这不是预期),而每个人都应该期望unique_ptr::get 很快。

    结合了这两件事的类型具有不确定的性能特征。 get 是您想在性能关键代码中做的事情吗?也许,也许不是;这取决于假设在代码执行的那个时刻已经产生了值是否合理。

    您可以使用std::async 和std::launch::deferred 来使用future 来完成您想做的事情。 std::launch::deferred 确保“异步”进程将在与future::get 的调用者相同的线程上执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-10
      • 2017-05-06
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2016-08-25
      相关资源
      最近更新 更多