1

令我感到羞耻的是,我没有机会在实际开发中使用智能指针(主管认为它太“复杂”并且浪费时间)。但是,我计划将它们用于我自己的东西......

我遇到了关于在模块完成后或在加载新数据时取消初始化模块的情况。当我使用指针时,我发现我的代码中到处都是检查 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);

如果我要使用智能指针而不是原始指针,如何缓解这个问题?

4

3 回答 3

4

使您的每个类都实现一个析构函数,该析构函数执行该类所需的所有清理/取消初始化。

创建该类的一个实例,并将其包装在boost::shared_ptr.

然后将其副本传递给需要访问实例的每个函数。

并且智能指针将确保一旦对象不再被使用(当所有共享指针都被销毁时),它们指向的对象被销毁。它的析构函数被运行,所有的清理工作都被执行。

与 C++ 中的往常一样,尽可能使用 RAII。

每当你有类似x.reset()or的代码disconnect(x)时,你应该做的第一件事就是问自己“这不属于析构函数吗?”

此外,无论何时使用,x->y()您都应该问自己:

  • 为什么这是一个指针?我不能使用分配在堆栈上的单个实例,也许还有一些对它的引用吗?
  • 如果它必须是一个指针,为什么它不是一个智能指针?
于 2009-09-22T11:05:43.110 回答
2

智能指针主要是一种管理所指向内存的工具。它们并不意味着可以让您摆脱 NULL 值检查的负担......

在您的示例代码中,我认为智能指针降低代码复杂性的潜力不大,除非您将诸如videoPlayerWindow_->reset(),之类的调用移动disconnect(videoPlayerWindow_)到类的析构函数中,videoPlayerWindow是一个实例。

于 2009-09-22T10:30:10.620 回答
2

对 NULL 的检查不是问题——而且智能指针无论如何也不会干预。

于 2009-09-22T10:34:58.037 回答