2011-02-05 10 views
0

が、私はこのことについて質問がありますか?私はをAオブジェクトの代わりにBのコンストラクタに渡します。 intBのコンストラクタでAに変換されていますが、その理由は何ですか?C++の継承の質問

ありがとうございます。

Avri。

答えて

5

explicitコンパイラはiを使用してAのanomymousインスタンスを作成し、Bインスタンスを初期化するためにそれを使用しているとして、あなたはAコンストラクタを宣言していないので。コンパイラがこれらの暗黙的な変換を実行しないようにするには、costructorをexplicitと宣言します。その後、コンパイラエラーが発生します。 intからAへの変換がありますのでAintを取り、explicitはあなたが暗黙的にint変換することができますマークされていない単一のパラメータのコンストラクタを持っているので

1

、暗黙のうちにあなたのコードは

A* p = new B(A(i)); 
+0

great tnxなので、例えばintの代わりにchar *のような他の型を追加すると、Aは上記の型を扱うのに適切なc'torを持たないため、コンパイルされません。 – Avri

2

に翻訳されますA

Bのための唯一の現実的なコンストラクタはAかかりますので、あなたは、new B(i)を行うと、試行がAiを変換し、そこから新しいBを構築するために作られています。この変換は、を取るコンストラクタを使用して一時的にAを作成することによって行われます。 Bオブジェクトが構築されると

、基底クラスA、一時Aからメンバ変数apaのコピーを意味する一時Aから構築コピーです。

厳密には、コンストラクタがAオブジェクトを値で受け取るため、一時的に概念的には再びコピーされます。ただし、コンパイラはBのコンストラクタパラメータをiから直接作成することで一時的な効果をなくすことができますので、効果は単なるコピーのように見えます。一時的Aが破壊されたときに、delete paが動的に割り当てられたintが破壊されることになりますが、新しく割り当てられたBオブジェクトの基底クラスAは今も無いこのポインタのコピーを持っていますので

これは重大なエラーが発生します無効なオブジェクトの長点。コンパイラがコピーの1つを削除しない場合、すぐに「ダブルフリー」が発生します。

Aの主な特徴は、リソースアクション(割り当て解除)を実行するユーザー定義のデストラクタがあることです。これは、Aは、コンパイラ生成バージョンがAの設計と一貫して機能しない可能性があるため、ユーザー定義のコピーコンストラクタとコピー代入演算子が必要であるという強い警告です。

これは、デストラクタ、コピーコンストラクタ、またはコピー代入演算子のいずれかのユーザ定義バージョンが必要な場合、すべてのユーザ定義バージョンが必要になる可能性があるという3つのルールです。それら。

例では、動的に割り当てられたBオブジェクトを解放しようとしましたが、「ダブルフリー」エラーが発生する可能性があります。また、Aのデストラクタは、Aへのポインタを正しく削除するために、virtualとマークする必要があります。