C++ 和智能指针——智能指针在这种情况下有啥帮助?
Posted
技术标签:
【中文标题】C++ 和智能指针——智能指针在这种情况下有啥帮助?【英文标题】:C++ and Smart Pointers - how would smart pointers help in this situation?C++ 和智能指针——智能指针在这种情况下有什么帮助? 【发布时间】:2009-09-22 10:21:40 【问题描述】:很遗憾,我没有机会在实际开发中使用智能指针(主管认为它太“复杂”且浪费时间)。但是,我打算将它们用于我自己的东西......
我遇到过在模块完成后或在加载新数据时取消初始化模块的情况。当我使用指针时,我发现我的代码中充斥着诸如此类的 null 检查...
// TODO: Reset all opened windows
// Deinit track result player
if (trackResultPlayer_)
trackResultPlayer_->reset();
// disconnect track result player
disconnect(trackResultPlayer_);
disconnect(trackResultAnimator_);
if (videoPlayerWindow_)
videoPlayerWindow_->reset();
// Disconnect the video player window from source movie data
disconnect(videoPlayerWindow_);
// Disconnect this module from its children as they would be connected again
disconnect(this);
如果我要使用智能指针而不是原始指针,如何缓解这个问题?
【问题讨论】:
记住 new 不会返回 NULL(除非你明确要求)。 【参考方案1】:使您的每个类都实现一个析构函数,该析构函数执行该类所需的所有清理/取消初始化。
创建该类的一个实例,并将其包装在 boost::shared_ptr
中。
然后将其副本传递给需要访问实例的每个函数。
并且智能指针会确保一旦对象不再被使用(当所有共享指针都被销毁时),它们指向的对象被销毁。它的析构函数被运行,并且所有的清理工作都被执行了。
在 C++ 中,尽可能使用 RAII。
每当您有x.reset()
或disconnect(x)
之类的代码时,您首先应该问自己“这不属于析构函数吗?”
此外,每当您使用x->y()
时,您应该问自己:
【讨论】:
【参考方案2】:智能指针主要是一种管理所指向内存的工具。它们并不是为了让你摆脱 NULL 值检查的负担......
在您的示例代码中,我认为智能指针降低代码复杂性的潜力不大,除非您将 videoPlayerWindow_->reset()
、disconnect(videoPlayerWindow_)
等调用移至类的析构函数中,videoPlayerWindow
是一个实例的。
【讨论】:
-1。智能指针用于(并推荐)管理可以由多个所有者共享的任何类型的资源,而不仅仅是内存。 “它们并不是为了让你摆脱 NULL 值检查的负担”:一般来说是这样,但在这种特定情况下,NULL 检查是看是否需要清理,哪些智能指针带有适当的析构函数 会照顾。 “我认为智能指针降低代码复杂性的潜力不大,除非……”哈哈!比较:“我觉得食物没什么意义,除非你吃”。 我想我提到了析构函数。我无法推断(从 OP 给出的代码)在这里使用析构函数进行清理是否实际上是一种可行的方法。 我想我们不同意——对我来说,OP 的代码急需将那些if
块的内容放入析构函数中(特别是指针所在类的析构函数)测试为 NULL)。
果然,干净的解决方案是将清理代码移动到适当的析构函数中。另一方面:他在谈论“取消初始化一个模块”,我读为:“我有一堆指向一些全局变量中的对象的指针,我现在需要安全地处理它们”(对我来说,代码看起来是这样)。这就是让我怀疑只是在这里添加几行到一些析构函数代码并且有足够的重构来引入基于智能指针的“正确”解决方案。
我明白你的意思。是的,以“正确的方式”做事需要更多的关注和思考,而不是简单地将这些代码块移动到析构函数中——特别是 OP 需要重组事物,以便依赖于其他对象的对象通过智能指针包含它们。跨度>
【参考方案3】:
对 NULL 的检查不是问题 - 无论如何,智能指针也不会干预。
【讨论】:
以上是关于C++ 和智能指针——智能指针在这种情况下有啥帮助?的主要内容,如果未能解决你的问题,请参考以下文章