0

假设我有这个课程:

class Bear
{
public:
    Bear ();
    Bear (Bear &other);

    // ... methods

private:
    BearInfo* m_pInfo;
};

我可以按值Bear存储对象吗?根据文档:QList<Bear>

在内部,QList<T>表示为指向类型项的指针数组T。如果T本身是指针类型或不大于指针的基本类型,或者如果T是 Qt 的共享类之一,则将QList<T>项目直接存储在指针数组中。

虽然我的类只包含一个指针,但它既不是指针类型也不是基本类型,所以在我看来,QList将存储指针 ( Bear*),这不是我想要的。而且由于BearInfo结构必须是可变的,我不能BearQSharedDataPointer.

有什么建议可以让这个类按值存储在 Qt 集合中吗?

4

3 回答 3

2

只需使用 stl 容器,它随处可用,即使在 QT 中也是如此。

这是我所做的。:)

于 2011-06-01T21:08:04.453 回答
2

使用QVector,Qt 文档说明了这一点:

QList、QLinkedList 和 QVarLengthArray 提供类似的功能。这是一个概述:

  • 对于大多数用途,QList 是正确使用的类。像 prepend() 和 insert() 这样的操作通常比使用 QVector 更快,因为 QList 将其项目存储在内存中的方式(有关详细信息,请参阅算法复杂性),并且其基于索引的 API 比 QLinkedList 的基于迭代器的 API 更方便。它还扩展到您的可执行文件中的更少代码。
  • 如果你需要一个真正的链表,保证在链表中间插入恒定的时间并且迭代器指向项目而不是索引,使用 QLinkedList。
  • 如果您希望项目占据相邻的内存位置,或者如果您的项目大于指针并且您希望避免在插入时将它们单独分配到堆上的开销,则使用 QVector。
  • 如果您想要一个低级可变大小数组,QVarLengthArray 可能就足够了。
于 2011-06-01T21:18:13.817 回答
2

我可以 QList<Bear>按值存储 Bear 对象吗?

不。 您对文档的引用是正确的:在内部,QList<T>存储指向类型项目的指针T

取而代之的是 use QVector,它通过类型大于指针的值来存储对象(这就是它的目的)。

与 in 中的项目类似QList<>的问题是包含 by 的问题QVariant,它包含任何原始类型或其他一些小类型(如QDate)。QVariant因此,只有当您的值适合原语或指针时,您才能获得值语义。

如果您有一个对象容器,如QPointerQSharedPointer实例,则可以实现完全包含,这些容器在逻辑上共享和跟踪对(引用计数)对象等的引用。

与 STL(具有值语义)不同,Qt 依赖于“指向项”的容器,因为当这些项是多态的(派生类中的大小不同)时会出现问题。(这在面向对象的系统中很常见,这就是 Qt 默认使用指针语义的原因。)

例如,在 Qt 中,QList<Bear>这很好(实现为指向实例的指针的容器Bear),但是std::list<Bear>当所有 Bear 实例的大小不同时(例如,如果KodiakBearBlackBear派生自Bear,并且您添加了那些派生实例到std::list<Bear>班级)。在这种情况下,派生状态将通过值语义“剥离”。

于 2011-06-01T21:25:30.460 回答