-3

実際のオブジェクトが初期化される前にクラス メソッドが呼び出されるこの奇妙な動作/バグに気付きました。メソッドを持つラッパーオブジェクトがありますoperator->()。ここで、メソッドを使用してコンストラクターのコンストラクター パラメーターとしてオブジェクトを別のオブジェクトに渡すとoperator->()、実際のラッパー オブジェクトは構築されず、operator->()メソッドを実行するだけです。

実際のコード サンプルは非常に複雑で、他の多くの要素に依存しているため、適切にコンパイルされない可能性がある C++ コード スニペットのみを示します。

template<typename T>
class wrapper_object_type
{
public:
    wrapper_object_type() {/*does not run*/}
    T* operator->() {/*does run*/}
};
class bad_behaviour
{
public:
    bad_behaviour() : another_object(wrapper_object->t_object) 
    {/*crashes(0xccc access violation*/}
};

では、そのような動作を許可する可能性がある標準で定義されているものはありますか? またはより正確には、デフォルトの構築をバイパスできる暗黙の構築などがありますか?

4

2 に答える 2

2

おそらく、wrapper_object初期化される前に使用します。メンバー変数は、クラスで宣言されているのと同じ順序で構築されるため、 が のwrapper_object前に宣言されていることを確認してanother_objectください。

( とが のメンバー変数であると仮定wrapper_objectしますが、より合理的なコード サンプルがなければ、それを言うのは困難です。)another_objectbad_behaviour

于 2013-01-09T22:13:08.313 に答える
0

まあ、私は苦労しました。オブジェクトをスタックからヒープに切り替え、new初期化リストではなくキーワードを使用して明示的に初期化しました。思ったとおり、それは奇妙な動作を再現しなかったので、意図したとおりに機能しました。私が今考えているのは、実際にはコンパイラのバグである可能性があるということです。初期化子リストを介して行った方法は、問題を修正した方法と類似しているためです。変更された唯一のことは、以前はそれらをヒープに割り当てていなかったという事実です。

また、バグを再現する作業コードを提供しようとしましたが、バグは表示されませんでした。バグが発見された実際のコードは、テンプレート タイプとラッパー オブジェクトに大きく依存している可能性があります。オブジェクトがヒープに割り当てられたときに機能するようになったため、バグはコードではなくコンパイラにあります。

于 2013-01-10T15:03:18.313 に答える