我正在审查我在这个语句块中遇到的一段C ++代码:
static void Vector3DefaultConstructor(Vector3 *self)
{
new(self) Vector3();
}
我之前并没有以这种方式使用新的运算符。有人可以解释为什么以这种方式调用new?
答案 0 :(得分:3)
这称为“展示位置new
”。默认情况下,它不分配内存,而是在给定位置构建对象(此处为self
)。但是,对于一个班级来说,它可能会超载。
有关详细信息,请参阅FAQ。
使用展示位置new
销毁对象的正确方法是直接调用析构函数:
obj->~Vector3();
答案 1 :(得分:3)
有人可以解释为什么以这种方式调用新手?
我可以告诉你它的作用。它有效地在任意一块内存上调用构造函数,从而在该段内存中构造对象。常规new
既分配内存又构造该内存中的对象;安置新的只做后一部分。
至于为什么有人会写这段代码?没有线索。如果对象采用void*
而不是Vector3*
,则更有意义。但除非Vector3::Vector3()
是私有的,否则没有理由在这样的静态函数中隐藏放置新用法。
答案 2 :(得分:0)
真实世界示例:std::vector
分配足够的内存来存储其当前负载,以降低push_back
的平均成本。
如果它存储了T*data
缓冲区,那么调用data=new T[capacity]
将默认构造一堆T
个对象。麻烦的是,vector
的语义是它只包含你放入它的内容:我们可以预先为我们的对象分配内存,但那些对象不应该存在。
解决方案是使vector::data
成员成为void*
并为其分配无类型内存。现在每当我们向容器添加一个对象时,我们需要构造它以使该对象存在并为原始指针赋予意义。
template <typename T>
void vector <T> :: push_back (const T & value)
{
resize (m_size + 1);
// construct a new T in the void buffer.
new (reinterpret_cast <T*> (m_data) + m_size) T (value);
++ m_size;
}
template <typeame T>
void vector <T> :: pop_back ()
{
(reinterpret_cast <T*> (m_data) + m_size) -> ~ T ();
-- size;
}