这里有人用过c++的“placement new”吗?如果有,为什么?在我看来,它只在内存映射硬件上有用。
当前回答
脚本引擎可以在本机接口中使用它来从脚本分配本机对象。有关示例,请参阅Angelscript (www.angelcode.com/angelscript)。
其他回答
它可能在使用共享内存时很方便,在其他用途中…例如:http://www.boost.org/doc/libs/1_51_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.conditions.conditions_anonymous_example
如果你正在构建一个内核,它很有用——你把从磁盘或页表读取的内核代码放在哪里?你得知道该往哪里跳。
或者在其他非常罕见的情况下,比如当你有大量分配的空间,想要把几个结构放在彼此后面。它们可以这样打包,而不需要使用offset()操作符。不过,还有其他的技巧。
我也相信一些STL实现使用了新位置,比如std::vector。它们以这种方式为2^n个元素分配空间,而不需要总是realloc。
我也有个主意。 c++确实有零开销原则。 但是异常不遵循这个原则,所以有时它们会被编译器开关关闭。
让我们来看看这个例子:
#include <new>
#include <cstdio>
#include <cstdlib>
int main() {
struct A {
A() {
printf("A()\n");
}
~A() {
printf("~A()\n");
}
char data[1000000000000000000] = {}; // some very big number
};
try {
A *result = new A();
printf("new passed: %p\n", result);
delete result;
} catch (std::bad_alloc) {
printf("new failed\n");
}
}
我们在这里分配一个大的结构体,检查分配是否成功,然后删除它。
但是如果我们关闭了异常,我们就不能使用try block,并且无法处理new[]失败。
我们怎么做呢?以下是如何做到的:
#include <new>
#include <cstdio>
#include <cstdlib>
int main() {
struct A {
A() {
printf("A()\n");
}
~A() {
printf("~A()\n");
}
char data[1000000000000000000] = {}; // some very big number
};
void *buf = malloc(sizeof(A));
if (buf != nullptr) {
A *result = new(buf) A();
printf("new passed: %p\n", result);
result->~A();
free(result);
} else {
printf("new failed\n");
}
}
使用简单的malloc 检查是否是C方式失败 如果成功了,我们就使用新位置 手动调用析构函数(不能直接调用delete) 电话免费,由于我们叫malloc
UPD @Useless写了一个注释,它向我的视图打开了new(nothrow)的存在,在这种情况下应该使用它,但不是我之前写的方法。请不要使用我之前写的代码。对不起。
它被std::vector<>使用,因为std::vector<>通常分配比vector<>中的对象更多的内存。
在序列化时(比如使用boost::serialization),放置new也非常有用。在c++的10年里,这只是我第二次需要新职位的情况(如果你包括面试的话,这是第三次:))。
推荐文章
- 什么是“参数依赖查找”(又名ADL,或“Koenig查找”)?
- 公共朋友交换成员函数
- 如何在Go中使用c++
- 自定义c++分配器的引人注目的例子?
- RAII和c++中的智能指针
- 如何构建和使用谷歌TensorFlow c++ api
- 断言是邪恶的吗?
- 下面这些短语在c++中是什么意思:0 -,default-和value-initialization?
- 在STL地图中,使用map::insert比[]更好吗?
- C++ Linux的想法?
- 如何为Fedora安装g++ ?
- Std::cin输入空格?
- c++标准是否要求iostreams的性能很差,或者我只是在处理一个糟糕的实现?
- gcc在哪里查找C和c++头文件?
- 为什么我们需要require require ?