新的展示位置如何知道要创建哪个布局? [英] How does placement new know which layout to create?
问题描述
#include <iostream>
#include <typeinfo>
struct A { int a; };
struct B : virtual A { int b; };
struct C : virtual A { int c; };
struct D : B,C { int d; };
int main()
{
D complete;
B contiguous;
B & separate = complete;
B * p[2] = {&separate, &contiguous};
// two possible layouts for B:
std::cout<< (int)((char*)(void*) &p[0]->a -(char*)(void*)&p[0]->b)<<" "<< sizeof(*p[0])<< "\n";
std::cout<< (int)((char*)(void*) &p[1]->a -(char*)(void*)&p[1]->b)<<" "<< sizeof(*p[1])<< "\n";
alignas(B) char buff[sizeof(B)];
void * storage = static_cast<void*>(buff);
// new expression skips allocation function:
auto pointer= new (storage) B; // Which layout to create?
std::cout << typeid(pointer).name()<<"\n";
pointer->~B(); // Destructor knows layout through typed pointer.
}
// sample output (Debian 8, amd64):
// 24 16
// 4 16
// P1B
C ++ 14标准中是否有一个部分要求新建"以创建特定的布局?是否有保证 新创建的布局适合大小为sizeof(B)且偏移量为零的缓冲区吗?
Is there a section in the C++14 standard that reqires 'new' to create a particular layout? Is there guarantee that the layout created by new fits into a buffer of size sizeof(B) and with offset zero?
您能使用grep友好的术语还是提供参考?我在问题中添加了对标准的引用.
edit: Could you please use grep-friendly terminology or provide references? I added a reference to the standard to the question.
请考虑以上示例输出:数字24告诉您什么?缓冲区的大小是多少?
Take into consideration the sample output above: What does the number 24 tell you? What is the size of the buffer?
标准中可能有一个说法,即派生程度最高的对象始终是对象表示形式的直接且连续的副本, 但我还没有找到.
There might be a statement in the standard that a most derived object is always a straightforward, contiguous copy of the object representation, but I haven't found this one.
我们对new的了解是,它将与完整的对象类型一起使用. [expr.new]
The thing we know about new is that it shall be used with a complete object type. [expr.new]
在[class.dtor]§12.4(14)中有一个带有放置选项的new表达式示例.但是,该示例可能仅因为其中的类是标准布局而起作用.
There is an example for a new-expression with the placement option in [class.dtor] §12.4 (14). However, the example might work simply because the class therein is standard-layout.
推荐答案
哪里可以保证新创建的布局适合大小为sizeof(B)且偏移量为零的缓冲区
从new
中命名的类型开始,其参数为B
.正在生成B
,而不是D
.类型B
关于D
一无所知". D
的声明对B
没有影响;可以将B
声明放入不会出现D
的翻译单元中,但是程序中的每个地方都会对B
的大小和布局达成一致,无论是否也知道D
在那些地方.
From the the type being named in new
as its argument being B
. A B
is being made, not an D
. The type B
"knows nothing" about D
. The declaration of D
has no influence on B
; the B
declaration can be put into translation units in which D
doesn't appear, yet everywhere in the program there will be agreement about the size of B
and is layout, regardless of whether D
is also known in those places or not.
类型为T
的C ++对象的大小为sizeof T
.这意味着它适合sizeof T
个字节;表示(sizeof T) + k
字节不是必需的,其中k > 0
.
A C++ object of type T
has a size sizeof T
. This means that it fits into sizeof T
bytes; it cannot be the case that (sizeof T) + k
bytes are required for its representation, where k > 0
.
这篇关于新的展示位置如何知道要创建哪个布局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!