在我一直在研究的一些代码中,我将指针传递给不一定由它们传递给的类专门管理的类。如果类被销毁,那么我检查指针的内存是否已经被释放。我遇到的问题是,如果指针被释放并在调用类的析构函数之前设置为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;
}
正如预期的那样,输出是:
指针不为空
指针为空
当指针没有通过引用存储时,我最终得到一个悬空指针。
我的问题是这是否通常被认为是一种很好的编程习惯。这个解决方案有什么缺点,还是有更好的约定?
答案 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)
。