什么时候可以使用智能指针安全地包装来自工厂的遗留原始指针?

When is safe wrapping legacy raw pointers from factories with smart pointers?

什么时候可以安全地包裹智能指针(unique_ptr 或 shared_ptr)C++ 框架工厂返回的原始指针在 c++11 之前开始发展?

例如,当所有事情都发生在同一个函数中时:

int main(int argc,char** argv)
 {
  //.....
  auto* runManager = G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default);
  //... many lines later
  delete runManager;
 }

相信把返回的裸指针放在一个unique_ptr里,在函数末尾取出delete是无害的

但除了这种特定情况,我不确定是否还有其他情况可以安全地完成此操作 - 并且您的代码在可读性/可维护性方面的收益值得付出努力。

特别是我正在使用一个 C++ 框架工具包,它开发了自己的方式来跟踪和处理框架创建的对象,所以在以一种不适合的方式使用返回的指针之前,我应该三思(或更多)本来打算。

非常欢迎任何建议。

仅当返回值指向的对象的所有权转移给用户(即编写调用该工厂的代码的您)时。工厂返回的对象可能实际上由框架拥有,并且会被正确销毁并且(几乎)永远不会丢失。在这些上面使用智能指针会导致问题,主要是双重删除。

Qt 框架就是这样的一个例子,其中所有可视元素在被销毁时都会销毁它们的子元素,并且所有 QObject 元素都是“枚举”的。那里的工厂对用户是隐藏的,主要与 signal-slot 系统和元对象数据有关。在某些特殊情况下可以使用智能指针,但 Qt 提供了自己的风格。

不拥有创建的对象的工厂可能需要一些自定义步骤来直接删除对象,在这种情况下,您应该为智能指针使用适当的删除器。

现代C++中“原始指针不好”的说法有点误解。它实际上必须写成“原始 拥有 指针是不好的”。如果您释放了原始指针的值,并且程序中没有任何内容为了适当的重新分配和释放资源而存储它的值,那么它就是一个拥有指针。