【发布时间】:2016-01-27 14:20:58
【问题描述】:
我可以看到这些类被视为调用默认构造函数所需的复杂对象:
void QVector<T>::defaultConstruct(T *from, T *to)
{
if (QTypeInfo<T>::isComplex) {
while (from != to) {
new (from++) T();
}
...
}
但不清楚为什么需要在 QVector 的“隐藏”区域中构造对象。我的意思是这些对象根本无法访问,那么为什么不只是保留内存而不是真正的对象创建呢?
作为一个额外的问题,我想问一下,如果我想要一组非默认可收缩对象,我可以安全地将QVector<T> 替换为QVector<Wrapper<T> 吗?其中Wrapper 是这样的:
class Wrapper {
public:
union {
T object;
bool hack;
};
Wrapper() {}
Wrapper(const T &t) : object { t } {}
Wrapper(const Wrapper &t) : object { t.object } {}
Wrapper &operator=(const Wrapper &value) {
object = value.object;
return *this;
}
~Wrapper() {}
};
【问题讨论】:
-
如果一个对象没有默认构造函数,通常是有原因的。我建议不要黑客攻击。也许尝试将
std::unique_ptr存储在您的包装器中。 -
默认构造函数被
QVector(int)和resize(int)用于向量中实际存在的元素。 -
@NeilKirk 我没有看到使用
std::unique_ptr比这个hack 有任何优势,而在磨削内存方面有一个巨大的劣势,这将使QVector本身的优势化为乌有。另外,请不要忘记,std::vector不需要具有默认构造函数。 -
不,placement new 允许您将对象放入您选择的缓冲区中。它可能是您的包装器的成员。如果您尝试使用您的对象 - 包括将新对象复制到其中 - 当它使用“默认构造函数”创建时,由于您的 hack,这是未定义的行为。
-
T QVector::value(int i) const还需要一个默认构造函数,因为如果索引超出范围,您将获得一个默认值。
标签: c++ qt containers qvector