3

以下の例のようなコードが C++ で多く見られますが、これは通常、規則として推奨されています。

class Foo
{
public:

    Foo()
    {
        bar = new int[100];
        size = 100;
    }

    // ... copy/assignment stuff ...

    ~Foo()
    {
        if (bar) // <--- needed?
        {
            delete[] bar;
            bar = nullptr; // <--- needed?
        }

        size = 0; // <--- needed?
    }

private:

    int* bar;
    int size;
};

私にとって、 、if (bar) { ... }bar = nullptr;およびの 3 つのステートメントは、size = 0;次の 2 つの理由で冗長です。

  1. delete nullptr;完全に安全で、何もしません。
  2. オブジェクトが破棄されてメモリが解放された場合、0に設定barする安全性について心配する必要はありません。nullptrsize

これらの正当化は正しいですか?これらのステートメントは本当に冗長ですか? もしそうなら、なぜ人々はそれらを使用し、提案し続けるのですか? この慣習を守ることで解決できる潜在的な問題をいくつか見てみたいと思います。

4

4 に答える 4

6

そうです、それらは不要であり、一部のコンパイラはいずれにせよそれらを最適化します。

ただし、人々が通常これを行う理由は、問題を見つけやすくするためです。たとえば、ポインターを null に設定しないとします。オブジェクトは破棄されますが、(以前は) ポインターに誤ってアクセスしようとしました。ランタイムはおそらくそれをクリアしないため、有効なものがまだそこに表示されます。これはデバッグからのみ価値があり、まだ未定義の動作ですが、時には報われることがあります。

于 2013-07-18T15:59:35.480 に答える
4

これはどこusually recommended as a conventionですか?

通常、メモリ割り当てを手動で管理しないことをお勧めします。これを実装するために a std::vector(または本当に必要な場合はスマート ポインター) を使用した場合、すべての問題は完全に解消され、デストラクタを記述する必要はまったくありません。

ただし、これを行うことを本当に主張している場合 (そして、正確さのために、ここに示していないコピー コンストラクター/コピー割り当てを記述している場合)、デストラクタでの余分な作業が実際に何が起こっているのかを実際に隠し、ほとんど提供しないことがわかります。コードの難読化を犠牲にして価値を高めます。

于 2013-07-18T16:18:05.823 に答える