【问题标题】:Qt and auto_ptrQt 和 auto_ptr
【发布时间】:2010-05-21 17:31:08
【问题描述】:

我刚刚发现了 auto_ptr 的概念并且很喜欢它!由于 Qt 经常需要 QList 或 QVector,所以有什么具体的理由应该避免使用 auto_ptr。如果我是对的,它允许你替换这个:

std::vector<MyClass*> vec;
/* add several elements to the vector and do stuff with them */
for(size_t i=0; i<vec.length(); ++i)
{
    delete vec[i];
}
vec.clear();

一些更短的东西(即没有清理)

std::vector<auto_ptr<MyClass>> vec;
/* add several elements to the vector and do stuff with them */
// no need for the delete loop

...Qt 仍然可以使用 auto_ptr 的共享内存魔法吗?父子自动内存管理是否仍然透明运行?谢谢

【问题讨论】:

  • You don't want to use a container of auto_ptr objects。你可以改用shared_ptr,虽然我从来没有用过Qt,也不能说它在各种形式的智能指针上的表现如何。
  • 或者你可以使用一个专门用来存放指针的容器。 boost:ptr_vector
  • @Martin,或者更好的是,您可以使用 QVector,它也被设计为指针向量,按值保存小于指针的类型,并提供 Qt 容器的所有优点。
  • @iconiK:我对 QVector 不是很熟悉。但是阅读文档并不能保证向量接管所包含指针的所有权并在向量被销毁时销毁它们,从而导致 boost:ptr_vector 应该解决的所有问题。
  • @Martin,错误,我的意思是 QList (对 SO 感到厌倦并不好)。 QVector 等价于 std::vector。

标签: c++ qt auto-ptr


【解决方案1】:

Qt 有自己的智能指针类,在很多方面都优于std::auto_ptr,特别是其中一些可以毫无问题地放入容器中。 std::auto_ptr 具有所有权转移复制语义,因此如果您尝试将其放入容器中,将无法按预期工作。

尝试使用QSharedPointer。它是一个引用计数的智能指针,当智能指针的副本不再存在时,它会删除其包含的对象。与std::auto_ptr 不同,同一QSharedPointer 可以同时有多个副本,因此它可以很好地与容器配合使用。

【讨论】:

  • QSharedPointer 是否比 boost::shared_ptr 或更标准的 std::tr1:shared_ptr 更好?
  • 它们具有相同的语义,我想不出它们中的任何一个比另一个更有优势。但是如果项目已经在使用 Qt,那么引入对 boost 或 TR1 扩展的依赖只是为了使用这些类是没有意义的。
【解决方案2】:

如果您想要一个拥有指针所有权的容器,请查看提升指针容器。

您将指针放入容器中,但与其他容器一样,它们随后被视为普通对象,这使得它们更容易与标准算法一起使用(即无需编写包装类)。当指针容器超出范围时,它将对容器中的所有指针调用 delete:

boost::ptr_vector<MyClass>   v;
v.push_back(new MyClass(12));

std::for_each(v.begin(), v.end(), DoStuff());

// Destroyed here.

【讨论】:

    【解决方案3】:

    std::auto_ptr 不能用于std::vector,因为std::vector 期望能够复制其内容,而不能复制正常意义上的std::auto_ptr。复制意味着以两个相同的东西结束,如果你有两个相同的std::auto_ptrs,当它们超出范围时,它们指向的内容将被双重释放。 (取而代之的是,被复制的 auto_ptr 的内部指针被清零,而被复制到的指针现在是旧指针。)

    使用shared_ptr,通常以boost::shared_ptr 或Visual C++ 上的std::tr1::shared_ptr 的形式提供,并且将在C++0x 标准库中,或者使用Qt 拥有的任何东西。这些可以被复制,因此可以进入容器。

    【讨论】:

      猜你喜欢
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      相关资源
      最近更新 更多