在类中存储指针引用:良好的编程习惯?

时间:2013-12-11 18:46:02

标签: c++ pointers

在我一直在研究的一些代码中,我将指针传递给不一定由它们传递给的类专门管理的类。如果类被销毁,那么我检查指针的内存是否已经被释放。我遇到的问题是,如果指针被释放并在调用类的析构函数之前设置为NULL,那么我最终会得到一个悬空指针。该类最终看到指针仍然是非NULL并尝试删除它导致分段错误。我能想到的最好的解决方案是通过引用存储指针,如下所示:

class PtrReferenceClass {
 public:
  PtrReferenceClass(int*& i_) : i(i_) {}
  void run() {
    if(i == NULL)
      cout << "pointer is null\n";
    else
      cout << "pointer isn't null\n";
  }
  int*& i;
};

int main() {
  int* i = new int(5);
  PtrReferenceClass test(i);
  test.run();
  delete i;
  i = NULL;
  test.run();
  return 0;
}

正如预期的那样,输出是:
指针不为空
指针为空

当指针没有通过引用存储时,我最终得到一个悬空指针。

我的问题是这是否通常被认为是一种很好的编程习惯。这个解决方案有什么缺点,还是有更好的约定?

5 个答案:

答案 0 :(得分:2)

您可以在PtrReferenceClass的析构函数中检查NULLness。一个更好的选择是使用shared_ptr或真正澄清i的所有权。

答案 1 :(得分:2)

这取决于你想要完成的事情。 如果你想让你的类周围的内存使用C ++ 11的std::shared_ptr到处而不是int *。 如果您不需要课程内存,请使用C ++ 11的std::weak_ptr

至于保持类中的指针,如果它们被包装在C ++的指针包装器中,那就不错了。你可以直接使用原始指针,但一般情况下,只有在速度是一个极端问题时才应该这样做。

答案 2 :(得分:1)

在主线评论中同意@Paranaix以及@ToniBig,我真的不能想到你需要它的情况。这样的事情可能是为了防止可怕的程序员错误。您还应该记住,您正在存储对指针i的引用,并且当指针 i超出范围时,该引用将保持悬空,无论内存i引用是否已取消分配。总而言之,请不要这样做。

答案 3 :(得分:1)

你所做的就是为另一个人交换一生的问题。新问题可能更容易解决......或者可能没有。

现在你可以检测到对象已经消失......只要某些东西使指针变量保持活着状态。

仔细考虑你的变量生命周期,以及指针引用(或等效指针指针)是否有意义应该变得清晰。

确实存在双重间接有价值的情况。我会给你一个引用:"Any problem in computer science can be solved by adding another layer of indirection"

答案 4 :(得分:1)

这些是选项:

  • 赋予类所有权并管理其中的生命周期 setter方法,用于在需要时更改它。如果您必须在外部创建或获取该指针,请再次执行此操作,否则只需执行所有操作。

  • 只将指针传递给将使用它的方法以及何时使用 需要的。void run(int* i)