Placement new 来初始化就地对象
我最近遇到了一种相当有趣的序列化方法,该方法利用未初始化变量的透明度(编译器中常见的未定义行为?)来实现“高效”反序列化。
内存被分配并分配有预定值。然后使用 Placement new 来实例化一个结构(例如复杂的就地数据结构),将未初始化的变量“初始化”为底层内存的值。 (参见下面的代码)
除了相当有风险并且可能不是一个非常令人愉快的编码约定之外......我只是想知道是否有人遇到过这种方法或更重要的是 - 它叫什么?
class SomeClass {
public:
SomeClass() {}
int someInt;
};
int main(...) {
int dummy = 42;
int *pSomeClass = new (&dummy) SomeClass();
cout << pSomeClass->someInt << endl;
}
这将打印出数字 42...neato!
I recently came across a rather interesting serialization approach that utilized the transparency (common undefined behavior among compilers?) of uninitialized variables for "efficient" deserialization.
Memory is allocated and assigned a predetermined value. Placement new is then used to instantiate a struct (for example a complex inplace data structure) "initializing" the uninitialized variables to the value of the underlying memory. (see code below)
Besides from being rather risky and possibly not a very agreeable coding convention... I was just wondering whether anyone had come across this method or more importantly -- what is it called?
class SomeClass {
public:
SomeClass() {}
int someInt;
};
int main(...) {
int dummy = 42;
int *pSomeClass = new (&dummy) SomeClass();
cout << pSomeClass->someInt << endl;
}
This will print out the number 42... neato!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是所谓的“靠UB”,或者通俗地说,就是“愚”。
It's called "relying on UB" or, in laymen's terms, "foolishness".
我在 eCos(一种 RTOS)中看到过这样做,以初始化一些内核对象。
正如托马拉克所指出的,缺点之一是不允许使用虚拟函数。
他们试图通过测试大小相等来确保
sizeof(kernel object) == sizeof(variable used for初始化)
。尽管他们的代码更复杂,但使用 C 结构来模拟 c 接口的 C++ 类成员变量,而不是使用 C 函数来获取/设置 C++ 类中的变量。
尽管他们的行为完全相反,他们使用在构造函数中设置的 C++ 类中的值来填充
placement new
中的内存。我不建议这样做。
I have seen this done in eCos, an RTOS, to initialize some of their kernel objects.
As pointed out by Tomalak one of the draw-backs is no virtual functions allowed.
They try to ensure that by testing for equal size
sizeof(kernel object) == sizeof(variable used for initialization)
.Their code although was way more complex using a C-struct to mimic the C++ class member variables for the c interface instead of using C functions to get/set the variables in the C++ class
Although the behaviour they went for there was the exact opposite, they used values from the C++ class, set in the constructor, to fill the memory from
placement new
.I do not advise on doing this tho.