C++ スライスの例から変更した次のコードの動作を理解するのに問題があります。
#include <stdio.h>
#include <iostream>
struct B {
int x;
B() { x = 0; }
virtual void foo( const char* id ) {
std::cout << id << ": B=" << this << ", x=" << x << std::endl;
}
};
struct D1 : B {
int y;
D1() { x = 1; y = 100; }
virtual void foo( const char* id ) {
std::cout << id << ": D1=" << this << ", x=" << x << ", y=" << y << std::endl;
}
} d1;
struct D2 : B {
int z;
D2() { x = 2; z = 200; }
virtual void foo( const char* id ) {
std::cout << id << ": D2=" << this << ", x=" << x << ", z=" << z << std::endl;
}
} d2;
void main() {
std::cout << "d1 = " << &d1 << std::endl;
std::cout << "d2 = " << &d2 << std::endl;
std::cout << "By pointer at beginning: " << std::endl;
B* pb = &d1;
pb->foo( "pd1" );
pb = &d2;
pb->foo( "pd2" );
std::cout << "By Value: " << std::endl;
B b = d1;
b.foo( "d1" );
b = d2;
b.foo( "d2" );
std::cout << "By pointer after by value: " << std::endl;
pb = &d1;
pb->foo( "pd1" );
pb = &d2;
pb->foo( "pd2" );
std::cout << "By reference: " << std::endl;
B& rb = d1;
rb.foo( "rd1" );
rb = d2;
rb.foo( "rd2" );
std::cout << "By pointer after by reference: " << std::endl;
pb = &d1;
pb->foo( "pd1" );
pb = &d2;
pb->foo( "pd2" );
}
//The result is the following:
d1 = 0115B504
d2 = 0115B510
By pointer at beginning:
pd1: D1=0115B504, x=1, y=100
pd2: D2=0115B510, x=2, z=200
By Value:
d1: B=0036FE44, x=1
d2: B=0036FE44, x=2
By pointer after by value:
pd1: D1=0115B504, x=1, y=100
pd2: D2=0115B510, x=2, z=200
By reference:
rd1: D1=0115B504, x=1, y=100
rd2: D1=0115B504, x=2, y=100
By pointer after by reference:
pd1: D1=0115B504, x=2, y=100
pd2: D2=0115B510, x=2, z=200
上記の結果から、次のことがわかります。
- 値の割り当ては、派生した特定のメンバーを削除することにより、割り当て先 (b) にスライスの問題を引き起こしますが、割り当て元 (d1 および d2) はそのまま残します。
- 参照代入は、派生した特定のメンバを代入しないことで代入先(rd)へのスライスが発生し、代入元(d1、d2)を部分的に変更します。
最初は、悪名高い C++ キャスト システムに気付くまで、ベースを介して別の型 (D2 から D1) への参照を割り当てることができることに驚きました。1 つの結論は、参照は初期化のみが可能であり、割り当てはできないようです。
リストを除いて、他のすべてのSTLコンテナはオブジェクトをコピーするため、ベースオブジェクトのSTLコンテナにスライスの問題があることがわかっています。ポインターを内部に保存しない限り、ベース参照用の STL コンテナーはそれほど良くないように見えます。
皆さんはこの問題にどのように対処しますか?
ありがとう!CP