在容器中使用新放置位置
Using placement new in a container
我刚刚在C++遇到了一些容器实现。该类使用内部缓冲区来管理其对象。这是一个没有安全检查的简化版本:
template <typename E> class Container
{
public:
Container() : buffer(new E[100]), size(0) {}
~Container() { delete [] buffer; }
void Add() { buffer[size] = E(); size++; }
void Remove() { size--; buffer[size].~E(); }
private:
E* buffer;
int size;
};
AFAIK 这将在Container()
中冗余地构造/销毁E
对象,如果未自定义new
/delete
,则~Container()
。这似乎很危险。
在Add()
中使用放置new
是防止危险的冗余构造函数/析构函数调用的最佳方法(除了将类绑定到功能齐全的池之外(?
使用放置new
时,new char[sizeof(E)*100]
是分配缓冲区的正确方法吗?
AFAIK 这将冗余地构造/销毁
E
对象
看起来是这样。new
ed数组已经应用了默认构造函数,delete[]
也会为所有元素调用析构函数。实际上,Add()
和 Remove()
方法除了维护size
计数器外,几乎没有其他作用。
使用放置 new 时,
new char[sizeof(E)*100]
是分配缓冲区的正确方法吗?
最好的方法是选择已经为您处理所有内存问题的std::allocator
。
使用放置new
并自行管理内存需要您了解许多问题(包括(;
- 对准
- 分配和使用的大小
- 破坏
- 安置等建筑问题
- 可能的别名
这些都不是无法克服的,它刚刚在标准库中完成。如果你有兴趣追求自定义分配器,全局分配函数(void* operator new (std::size_t count);
(将是内存分配的适当起点。
如果没有进一步解释代码的原始用途 - std::vector
或std::array
将是管理容器中元素的更好选择。
代码存在许多问题。如果在调用Add()
之前调用Remove()
则将对已破坏的对象执行赋值。
否则,delete[] buffer
将调用数组中 100 个对象的析构函数。以前可能叫过。
这是一个有效的程序:
#include <iostream>
int counter=0;
class Example {
public:
Example():ID(++counter){
std::cout<<"constructing "<<ID<<std::endl;
}
~Example(){
std::cout<<"destructing "<<ID<<std::endl;
ID=-1;
}
private:
int ID;
};
template <typename E> class Container
{
public:
Container() : buffer(new char [100*sizeof(E)]), size(0) {}
~Container() {
for(size_t i=0;i<size;++i){
reinterpret_cast<E*>(buffer)[i].~E();
}
delete [] buffer;
}
void Add() { new (buffer+sizeof(E)*size) E(); size++; }
void Remove() { reinterpret_cast<E*>(buffer)[--size].~E(); }
private:
void* buffer;
size_t size;
};
int main() {
Container<Example> empty;
Container<Example> single;
Container<Example> more;
single.Add();
more.Add();
more.Remove();
more.Add();
more.Add();
more.Remove();
return 0;
}
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- 我的 cout 上有一个奇怪的输出,它把答案放在第一位,然后在我调用它的地方放一个奇怪的输出.我该怎么办?
- 一个32位版本的应用程序,建立在CentOS 6 x64上,当在较新的Linux上启动时,在"dl_itera
- 有没有办法通过插入新类型名称而不是 int 来使用 2 位大小类型而不是 int?
- 32 位整数缩放,无溢出
- 新的 C++14 位分隔符处"Bad Character" Eclipse Oxygen 错误
- C++ WinRT - 如何动态缩放可写位图以匹配当前屏幕分辨率
- 重置QMENU以接受新的Qactions
- 在 c++ 中不能将超过 10 位数字放入一个变量中
- 内置运算符(新的,删除和函数调用除外)如何返回
- C++,打开和编辑文本文件中的数字数据,并将结果放入新文件中
- 方便的标志处理,所有标志都不能放入64位
- 将 int 放入 char 数组是否在法律上需要新的放置
- 如何将 32 位有符号整数放入更高的 32 位 64 位无符号整数中
- 如何仅使用数学方法旋转16x16位图数组的内容(无缩放,只需剪切角)
- Allegro 5如何绘制缩放位图区域
- 如何将整数位放入浮点
- 如何读取和重置字符位
- 重置对象m_object=对象(新,参数);
- 我可以使用放置新重置一个对象内的shared_ptr