动态指向现有对象或创建新对象

Posted

技术标签:

【中文标题】动态指向现有对象或创建新对象【英文标题】:Dynamically point to existing or create new object 【发布时间】:2019-07-10 13:42:27 【问题描述】:

我有一个函数,它使用存储在结构 A 中的信息。这个函数经常被调用,而且大多数时候它只能依赖存储在 A 中的信息。 在某些(罕见的)条件下,不能使用 A 的对象之一。必须创建一个新对象,并且它的寿命不应超过该函数(因为它只能使用一次并使用大量存储空间)。 我有一些伪代码来演示我的问题。目前我真的不喜欢它,因为对“new”的调用,但我想不出另一种方法来使用智能指针来实现这一点。

正如我在每本书中读到的那样,您现在不应该直接使用指针并依赖智能指针,我不确定,能否正确实现我想要的。

struct A
  myData data;


void often_called_function(int i, A &structA)


  // Pointer which shall dynamically point to existing or newly created object
  myData *current_data;

  // we rarely land here, data can't be used
  if (i == 10) 
    current_data = new myData(special arguments);
    current_data->reinit(i);
  
  // most of the time we land here, no need to re-create data, just reinit existing data from struct A
  else 
    structA.data.reinit(i);
    current_data = &structA.data;
  

  // do more stuff with current_data
  current_data->do_something(); 

所以基本上我正在寻找一种“更好”且安全的方法来完成此任务,有人可以帮助我吗? 提前致谢

【问题讨论】:

使用shared_ptr怎么样? 不会共享指针,如果我在 else 中分配“&structA.data”给它,当它超出范围时尝试销毁 structA.data(所以在函数结束后)? 【参考方案1】:

您可以创建一个智能指针来拥有新对象并在函数结束时释放它,但除非您需要创建新对象,否则请将其设为空。当你创建它时,只需让current_data 引用智能指针管理的对象:

void often_called_function(int i, A &structA)


  // Pointer which shall dynamically point to existing or newly created object
  myData *current_data;
  // smart pointer that will own the dynamically-created object, if needed:
  std::unique_ptr<myData> owner;

  // we rarely land here, data can't be used
  if (i == 10)
    owner = std::make_unique<myData>(special_arguments);
    current_data = owner.get();
    current_data->reinit(i);
  
  // most of the time we land here, no need to re-create data, just reinit existing data from struct A
  else
    structA.data.reinit(i);
    current_data = &structA.data;
  

  // do more stuff with current_data
  current_data->do_something();

注意看起来您可以通过将 reinit(i) 调用移出条件分支来稍微简化函数:

  // we rarely land here, data can't be used
  if (i == 10)
    owner = std::make_unique<myData>(special_arguments);
    current_data = owner.get();
  
  // most of the time we land here, no need to re-create data, just reinit existing data from struct A
  else
    current_data = &structA.data;
  
  current_data->reinit(i);

【讨论】:

以上是关于动态指向现有对象或创建新对象的主要内容,如果未能解决你的问题,请参考以下文章

获取指向现有 COM 对象的指针?

动态数组 C++,新 Obj[size] 的麻烦只创建 1 个对象指针,而不是数组

这是加载现有否则创建新 NSManagedObjects 的最佳方式吗?

原型模式

Protobuf-Net 似乎重用现有对象而不是创建和分配新对象

Laravel Cashier - 使用现有客户对象创建新订阅