【问题标题】:How do you replicate a changing pointer with C++ smart pointer?如何使用 C++ 智能指针复制更改指针?
【发布时间】:2016-03-18 22:36:31
【问题描述】:
struct A {
   int val;
};
struct B {
    int val2;
    A* ptr = nullptr;
};

int main() {
    A a1, a2;
    B b;
    if (...) { B.ptr = &a1; } else { B.ptr = &a2; }
    return 0;
}

如何用智能指针表示指针?它不拥有但需要访问对象 a1 和 a2。 B 仅“使用”a1 或 a2 之一,稍后可能会切换。

更改 ptr 并不意味着当然应该删除 a1 或 a2。所以,unique_ptr.reset() 不是解决方案。

【问题讨论】:

  • 您需要什么样的“智能”?通常智能指针用于管理所有权和生命周期,这在这里不是问题。
  • 如果它不拥有指针,那么只需使用原始指针,不需要智能。
  • 在使用智能指针而不是A* 时遇到什么问题?
  • Galik 的评论已经是正确的答案。未来,C++17 将提供observer_ptr 在这些情况下使用,这有助于使指针的预期用途更加清晰(也避免错误地调用delete)。

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


【解决方案1】:

在这种特殊情况下,您不需要智能指针来删除 a1 或 a2。

所以看起来根本不需要智能指针......

除非您希望在 b 超出范围时仅对其中一个对象执行一些特殊的清理代码。

在这种情况下,它看起来像这样:

struct A {
   int val = 0;
};

struct cleanup_A {
  void operator()(A* pa) const {
    if (pa) { my_cleanup_action(*pa); }
  }
};

struct B {
  using special_A_ptr = std::unique_ptr<A, cleanup_A>;
  int val2 = 0;
  special_A_ptr ptr = { nullptr, cleanup_A() };
};

int main() {
  A a1,a2;
  B b;
  if (...) { b.ptr.reset(&a1); } else { b.ptr.reset(&a2); }
  return 0;
}

当然,在这种非标准使用的情况下,所有常见的警告都适用......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 2014-03-10
    相关资源
    最近更新 更多