キャスト演算子を実際に定義せずに、互換性のある非ポインター オブジェクトを変換できますか? したがって、B が A から継承する場合:
A a;
B b;
(A)b
独自のキャスト演算子を提供しないとコンパイルされますか?
編集:コンパイルされているようです。デフォルトの変換キャスト演算子があるためですか、それともコンパイラが互換性を認識し、たとえば代入でデフォルトのコピー コンストラクターまたは代入演算子を使用するためですか?
はい、コンパイルされます ( http://ideone.com/CXbeh0 )
デフォルトA
ではコピー可能です。コピー コンストラクターには signature がありますA::A(A const &)
。のインスタンスB
は暗黙的に に変換可能であるためA const &
、キャストはA
のコピー コンストラクターを使用して解決されます。
参照への変換は、(暗黙的に生成された) コピー代入演算子にも適用されるため、a = b
再び を使用してコンパイルしA &A::operator=(A const &)
ます。
新しいオブジェクトは B ではなくタイプ A であるため、B の元のインスタンスに追加された情報は含まれていないことに注意してください。それがあなたが望むことはめったにありません。
ちなみに、C++ では、C スタイルのキャストが存在することを忘れて、C++ のより具体的なキャスト タイプを使用することをお勧めします。
static_cast
互換性のあるタイプのみ。dynamic_cast
実行時チェックを使用してポインター/参照をアップキャストするための。const_cast
const のみを処理します。reinterpret_cast
、本当にポインターのトリックを行う必要がある場合は、エイリアシング ルールに注意してください。ユーザー定義のコンストラクターまたは演算子が定義されていない場合、次のようになります。
(A)b
次のように実装されます。
A(b) //Calls A copy-constructor: A::A(const A&)
つまり、引数から A のコピー構築のテンポラリを作成します。
これはオブジェクト スプライシングと呼ばれ、B のいくつかのフィールドをコピーしていて、他のフィールドをコピーしていないため、通常は悪い考えです。YMMV。