::new((void*)p)T(value) 的同义词函数调用;
Synonym function call for ::new((void*)p)T(value);
我正在尝试编写自己的 Allocator
,它可以在 STL 中使用。到目前为止,我几乎可以成功完成,但是有一个功能我遇到了问题:
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);
}
我不知道如何使用我自己的函数重写它,它用 value
.
替换 new
关键字初始化它
此函数 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
?
construct
函数中的 new
运算符根本不分配任何东西,它是一个 placement new 调用,它需要一个已经分配的块内存(需要事先以某种方式分配,并且至少与 sizeof(T)
一样大)并通过调用 T
的构造函数将其初始化为 T
对象,假装内存p
指向的是一个 T
对象。
::new int(7)
调用默认的 new
运算符,为 int
获取足够大的内存,并构造一个 int
,其值为 7
它。
::new(ptr) int(7)
接受一个名为 ptr
的 void*
,并构造一个 int
,其中的值为 7
。这叫做"placement new".
重要的部分是第二段中缺少的内容。它不创建 space,而是在一些现有的 space.
中构造一个对象
这就像说 ptr->T::T()
ptr->int::int(7)
我们“调用构造函数of
inton the memory location of
ptr, except
ptr->T::T( )or
ptr->int::int(7)are not valid syntaxes. Placement
new` 是在 C++ 中显式调用构造函数的方法。
类似地,ptr->~T()
或ptr->~int()
将调用位于ptr
的对象的析构函数(但是,没有~int
所以这是一个错误,除非int
是一个模板或依赖类型,在这种情况下它是一个伪析构函数并且调用它被忽略而不是产生错误)。
您很少想更改 construct
分配器中的默认实现。如果您的分配器想要跟踪对象的创建并附加有关其参数的信息,而无需侵入式地修改构造函数,则您可以这样做。但这是一个极端案例。
我正在尝试编写自己的 Allocator
,它可以在 STL 中使用。到目前为止,我几乎可以成功完成,但是有一个功能我遇到了问题:
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);
}
我不知道如何使用我自己的函数重写它,它用 value
.
new
关键字初始化它
此函数 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
?
construct
函数中的 new
运算符根本不分配任何东西,它是一个 placement new 调用,它需要一个已经分配的块内存(需要事先以某种方式分配,并且至少与 sizeof(T)
一样大)并通过调用 T
的构造函数将其初始化为 T
对象,假装内存p
指向的是一个 T
对象。
::new int(7)
调用默认的 new
运算符,为 int
获取足够大的内存,并构造一个 int
,其值为 7
它。
::new(ptr) int(7)
接受一个名为 ptr
的 void*
,并构造一个 int
,其中的值为 7
。这叫做"placement new".
重要的部分是第二段中缺少的内容。它不创建 space,而是在一些现有的 space.
中构造一个对象这就像说 ptr->T::T()
ptr->int::int(7)
我们“调用构造函数of
inton the memory location of
ptr, except
ptr->T::T( )or
ptr->int::int(7)are not valid syntaxes. Placement
new` 是在 C++ 中显式调用构造函数的方法。
类似地,ptr->~T()
或ptr->~int()
将调用位于ptr
的对象的析构函数(但是,没有~int
所以这是一个错误,除非int
是一个模板或依赖类型,在这种情况下它是一个伪析构函数并且调用它被忽略而不是产生错误)。
您很少想更改 construct
分配器中的默认实现。如果您的分配器想要跟踪对象的创建并附加有关其参数的信息,而无需侵入式地修改构造函数,则您可以这样做。但这是一个极端案例。