我记得在某处读到使用对智能指针的引用会导致内存损坏。这只是因为智能指针被销毁后使用了它的引用?或者引用计数搞砸了?
感谢您澄清
答案 0 :(得分:14)
假设你在这里谈论shared_ptr ......
这仅仅是因为使用了 之后的智能指针的引用 它被摧毁了?
这是一个很好的答案。您可能不完全知道您的引用所指的指针的生命周期。
要解决这个问题,你需要研究一下boost :: weak_ptr。它不参与引用计数。当你需要使用它时,它会给你一个shared_ptr,一旦你完成它就会消失。它还会告诉您何时收集了指针。
来自weak_ptr文档
weak_ptr类模板存储一个 对一个物体的“弱引用” 已经由shared_ptr管理。至 访问对象,一个weak_ptr即可 使用转换为shared_ptr shared_ptr构造函数或成员 功能锁。当最后一次 对象的shared_ptr消失了 对象被删除,尝试 从weak_ptr获取shared_ptr 引用已删除的实例 对象将失败:构造函数将 抛出类型的异常 boost :: bad_weak_ptr,和 weak_ptr :: lock将返回一个空 shared_ptr的。
注意方法expired()也会告诉你你的ptr是否还在。
答案 1 :(得分:5)
使用智能指针(或任何分配管理对象)时,您指望构造函数/析构函数中定义的行为来管理refs / derefs / locks / unlocks。因此,这些类型的对象必须是真正的对象才能正常执行。当你使用对这些对象(或指针)的引用时,你绕过了这个机制(并要求一个wedgie)。
答案 2 :(得分:3)
在很多情况下,对智能指针的引用是一个好主意。 一个明显的例子是智能指针类本身的赋值方法,它接受引用到另一个智能指针作为其参数。
创建一个接受智能指针引用的方法意味着该参数不会增加智能指针的内部引用计数。这可以提高性能 - 但可能不是很多。此外,该方法有很多东西不能用引用 - 或原始的智能指针。如果你知道这些是什么并避免它们,那么通过引用传递就可以了。当然,智能指针的目的是避免知道这些事情。
此外,如果您的方法修改智能指针参数的值,则需要传递作为参考,与任何其他类型一样。
答案 3 :(得分:1)
智能指针的“智能”部分由构造函数,析构函数,赋值运算符和智能指针类的其他函数管理。通过使用引用,您将绕过这些操作 - 初始化引用时不会调用构造函数,并且当引用超出范围时不会调用析构函数。
本质上,对智能指针的引用是一个愚蠢的指针,具有后者所带来的所有风险和陷阱。
答案 4 :(得分:0)
我们有定制的智能指针,我们总是习惯于传递'const refsomething&'
它不会增加或减少智能指针,因此 - 更重要的是 - 避免了对InterLockedIncrement / Decrement的调用,这反过来又避免了memory fence以及与之相关的所有事情:总线锁定,缓存失效,......
答案 5 :(得分:0)
将对智能指针的引用传递给函数是非常安全的,这是一个好主意。对象可能会消失,但智能指针不会,它将坐在那里,至少在函数返回之前说空。这是在其范围内对智能指针进行别名的最佳方法。如果你使用带有const修饰符的引用来引用它,那么你有一个智能的观察引用:
const smart_ptr<T>&
有趣且有用的是,const阻止你使用引用说明,使智能指针为空并删除对象,但它不会阻止原始智能指针使其自身归零,并且您的引用将反映该更改。
从函数返回对智能指针的引用要求各种麻烦。