この投稿では:
C++ ポインター: アドレスを変更せずに内容を変更しますか?
ユーザーの Eric Postpischil は、クラスのデストラクタを積極的に呼び出すという回答を提案しました。それは合法ですか?それは良いプログラミングと見なされますか?
私が質問する理由は、あるクラスで私の先生がそれは禁止されており、私たちは決してそれをしてはならないと言ったからです.彼は間違っていましたか?
投稿の質問と回答自体ですが、興味深いのは私の質問とはあまり関係ありません。
この投稿では:
C++ ポインター: アドレスを変更せずに内容を変更しますか?
ユーザーの Eric Postpischil は、クラスのデストラクタを積極的に呼び出すという回答を提案しました。それは合法ですか?それは良いプログラミングと見なされますか?
私が質問する理由は、あるクラスで私の先生がそれは禁止されており、私たちは決してそれをしてはならないと言ったからです.彼は間違っていましたか?
投稿の質問と回答自体ですが、興味深いのは私の質問とはあまり関係ありません。
動的オブジェクトの作成プロセスが 2 つの段階に「逆アセンブル」できるのと同じように、生のメモリ割り当てと実際の初期化 (たとえば、placement-new によるコンストラクター呼び出し) と同様に、動的オブジェクトを破棄するプロセスも「逆アセンブル」できます。実際の初期化解除 (デストラクタ呼び出し) と生メモリの割り当て解除の 2 つの段階に分けられます。(ご覧のとおり、2 つのプロセスは互いのミラー イメージです。)
これは、独自の raw メモリ割り当て/割り当て解除メカニズムを使用する場合に非常に役立ちます。確かに、多くの場合、 をオーバーロードすることで目的の効果を得ることができますが、operator new/delete
柔軟性が十分でなく、上記の手順を明示的に実行することを好む場合もあります。
そこで、デストラクタの直接呼び出しが便利な機能の例を 1 つ示します。他にもかなりの数があります。はい、それは完全に合法です。
クラスの先生がそんなことは絶対にしてはいけないと言ったとき、彼/彼女はおそらく、現在のカリキュラムの範囲内で、今のところそれを避けるべきだということを意味している. 学習を進めていくと、「絶対にやってはいけない」トリックの多くが、実際には「自分が何をしているのか分かっているなら、そうしてください」というカテゴリに属する非常に役立つテクニックであることがわかるでしょう。もちろん、この手法は低レベルのものであるため、乱用すべきではありません。
PSこの構文は、存在しないデストラクタを「呼び出す」ことができるため、正式には疑似デストラクタ呼び出しと呼ばれます。
typedef int INT;
INT i;
i.~INT(); // <- legal code, pseudo-destructor call, no op
上記はINT
、クラス型ではないためデストラクタを持たないという事実にもかかわらず、正当な C++ コードです。(やろうとしないでくださいi.~int()
- それは違法です。エイリアス化された型名は、非クラス型に使用する必要があります。)