同义词函数调用:: new((void *)p)T(value);

时间:2016-06-20 12:08:07

标签: c++11 stl new-operator allocator

我正在尝试编写可以在STL中使用的Allocator。到目前为止,我几乎可以成功完成,但有一个功能,我有我的问题:

STL中使用的Allocator应该提供函数construct [来自标准分配器的示例使用new& delete]:

// initialize elements of allocated storage p with value value
void construct (T* p, const T& value)
{
    ::new((void*)p)T(value);
}

我被困在如何使用我自己的函数重写它,它取代了用new初始化它的value关键字。

此函数construct例如在此代码中使用:fileLines.push_back( fileLine );

,其中

MyVector<MyString>      fileLines;
MyString                fileLine;

这些是typedefs,我使用自己的Allocator

template <typename T> using MyVector = std::vector<T, Allocator<T>>;
using MyString = std::basic_string<char, std::char_traits<char>, Allocator<char>>;

我很困惑,因为这里分配了一个pointerT,例如[当我理解正确时] MySstring

我是否正确理解指针 - 由new分配 - 将有10个字节,value123456789,然后将提供的value复制到新指针?

我的问题:

如何使用我自己的函数重写一行代码?对我来说,困难的点是如何得到value [可以有任何类型]的长度,以便我可以正确地确定分配块的长度以及如何复制它适用于所有可能的类型T

2 个答案:

答案 0 :(得分:6)

new函数中的construct运算符根本不会分配任何内容,而是位置新调用,它会占用已分配的内存块(需要以某种方式分配,并且至少与sizeof(T)一样大,并通过调用T的构造函数将其初始化为T对象,假装内存指向p是一个T对象。

答案 1 :(得分:2)

::new int(7)调用默认的new运算符,为int获取足够大的内存,并在其中构造值int的{​​{1}}。

7会使用名为::new(ptr) int(7)的{​​{1}},并在其中构建值void*的{​​{1}}。这被称为&#34;放置新&#34;。

重要的部分是第二段缺少的内容。它不会创建空间,而是在某个现有空间中构造对象。

就像说ptr int我们在其中调用构造函数7 int ptr->T::T() ptr ptr->int::int(7) ptr-&gt; T :: T()of ptr-&gt; int :: int(7)on the memory location of new`是在C ++中显式调用构造函数的方法。

同样,, exceptor会在位于are not valid syntaxes. Placement的对象上调用析构函数(但是,没有ptr->~T()因此这是一个错误,除非{{ 1}}是一个模板或依赖类型,在这种情况下它是一个伪析构函数,它被忽略而不是生成错误。

您很少想要从分配器中的默认实现更改ptr->~int()。如果您的分配器想要跟踪对象的创建并附加有关其参数的信息,而不是干扰地修改构造函数,则可以执行此操作。但这是一个极端的案例。