#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)で、オフセットがゼロのバッファに新しいフィットで作成されたレイアウトが保証されていますか?プレースメントはどのレイアウトを作成するのかを知っていますか?
編集:grep-friendly用語を使用していただくか、参考にしてください。標準への言及を質問に追加しました。
上記のサンプル出力を考慮してください:番号24とは何ですか?バッファのサイズは?
ほとんどの派生オブジェクトは常にオブジェクト表現の直接的な連続コピーであるという文が標準であるかもしれませんが、 が見つかりませんでした。
私たちが新しく知っていることは、完全なオブジェクトタイプで使用されることです。 [expr.new]
[class.dtor]§12.4(14)の配置オプションを使ったnew-expressionの例があります。しかし、そのクラスが標準レイアウトであるため、この例は単純に機能するかもしれません。
「k!= 0」ではないはずですか? –
@AlexisWilkeもし 'k'が' signed int'で負であれば、それが 'size_t'に追加されるとどうなりますか? :) – Kaz
私は確信していません...あなたは教えてください。しかし、おそらく私はそれが 'k> = 0'ではなく' k> = 0'でなければならないと言います。あなたは答えを書きました... –