有人可以解释一下这行代码吗

时间:2020-08-23 12:48:57

标签: c++ vector data-structures dynamic-arrays

我正在观看有关如何在C ++中实现自己的vector / dynamic_array的youtube视频。 我了解所有东西,除了像代码之类的东西之外,我是c ++的新手,并试图了解下划线数据结构的实现。 但是我没有看到像这样的代码行。 代码:

template<typename... Args>
T& EmplaceBack(Args&&... args) {
    if (m_Size >= m_Capacity) {
        ReAlloc(m_Capacity + m_Capacity / 2);
    }
    new(&m_Data[m_Size])T(std::forward<Args>(args)...); 
    return m_Data[m_Size++];
}

我不明白的那一行:

new(&m_Data[m_Size])T(std::forward<Args>(args)...);

该行代码实际上在做什么? 顺便说一句,我真的不知道std::forward是什么。 谢谢你的解释。 :)

1 个答案:

答案 0 :(得分:3)

此行代码在地址&m_Data [m_Size]处构造一个带有参数args ...的T类型对象。不涉及内存分配。

new(&m_Data[m_Size])T(std::forward<Args>(args)...);

让我们假设我们称为“常规” new运算符:

new T((std::forward<Args>(args)...);

这将分配大小等于sizeof(T)的内存,并在该内存地址处调用T类型的构造函数。 std::forward用于称为“完美转发”的技术。简而言之:没有副本,没有动作,没有任何传递方式-只是将参数提供给构造函数,就像您直接调用它一样。

但是,如果您已经预先分配了内存-许多容器(例如向量)的主要性能提升点,该怎么办? Placement new操作员是您的朋友。您为它提供了预分配内存的地址,并且它仅构造对象。而且以后不需要delete,因为您没有使用placement new分配任何东西!

那次破坏呢?通常,delete对象会自动调用析构函数。在这种情况下,您必须像这样直接调用对象的析构函数-t->~T();