我正在尝试编写可以在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>>;
我很困惑,因为这里分配了一个pointer
到T
,例如[当我理解正确时] MySstring
。
我是否正确理解指针 - 由new
分配 - 将有10个字节,value
为123456789
,然后将提供的value
复制到新指针?
我的问题:
如何使用我自己的函数重写一行代码?对我来说,困难的点是如何得到value
[可以有任何类型]的长度,以便我可以正确地确定分配块的长度以及如何复制它适用于所有可能的类型T
?
答案 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 ++中显式调用构造函数的方法。
同样,, except
或or
会在位于are not valid syntaxes. Placement
的对象上调用析构函数(但是,没有ptr->~T()
因此这是一个错误,除非{{ 1}}是一个模板或依赖类型,在这种情况下它是一个伪析构函数,它被忽略而不是生成错误。
您很少想要从分配器中的默认实现更改ptr->~int()
。如果您的分配器想要跟踪对象的创建并附加有关其参数的信息,而不是干扰地修改构造函数,则可以执行此操作。但这是一个极端的案例。