4

インターネットをブラウジングしているときに、この投稿に出くわしました。これには、これが含まれます

「(よく書かれています) C++ は、スタック自動オブジェクトをプリミティブと同じように機能させるために多大な努力を払っています。これは、Stroustrup の「int と同じように行う」というアドバイスに反映されています。これには、オブジェクト指向開発の原則をより厳守する必要があります。あなたのクラスは、(int のように) 作成され、コピーされ、自動スタックとして正しく破棄されることを保証する「3 つのルール」に従って、int のように「機能する」まで正しくありません。」

私は少し C と C++ のコードを書いたことがあります。

誰かが例を挙げることができますか?

4

5 に答える 5

12

スタック オブジェクトは、コンパイラによって自動的に処理されます。

スコープを離れると削除されます。

{
   obj a;
} // a is destroyed here

「newed」オブジェクトで同じことを行うと、メモリ リークが発生します。

{
    obj* b = new obj;
}

b は破棄されないため、b が所有するメモリを再利用する機能を失いました。さらに悪いことに、オブジェクトはそれ自体をクリーンアップできません。

C では、以下が一般的です。

{
   FILE* pF = fopen( ... );
   // ... do sth with pF
   fclose( pF );
}

C++ では、次のように記述します。

{
   std::fstream f( ... );
   // do sth with f
} // here f gets auto magically destroyed and the destructor frees the file

C サンプルで fclose を呼び出すのを忘れた場合、ファイルは閉じられず、他のプログラムで使用されない可能性があります。(例: 削除できません)。

別の例では、オブジェクト文字列を示します。このオブジェクト文字列は、構築、代入が可能で、スコープを出ると破棄されます。

{
   string v( "bob" );
   string k;

   v = k
   // v now contains "bob"
} // v + k are destroyed here, and any memory used by v + k is freed
于 2008-08-27T13:59:22.387 に答える
2

他の回答に加えて:

実際、C++ 言語にはauto、オブジェクトのストレージ クラスを明示的に宣言するためのキーワードがあります。もちろん、これはローカル変数の暗黙のストレージ クラスであり、どこでも使用できないため、まったく不要です。の反対autostatic(ローカルとグローバルの両方) です。

次の 2 つの宣言は同等です。

int main() {
    int a;
    auto int b;
}

このキーワードはまったく役に立たないため、実際には次の C++ 標準 (「C++0x」) で再利用され、新しい意味が得られます。つまり、コンパイラが初期化から変数の型を推測できるようになります ( varC# のように)。

auto a = std::max(1.0, 4.0); // `a` now has type double.
于 2008-08-27T14:15:57.243 に答える
1

間違っている場合は訂正してください。ただし、自動スタック クリーニングを最大限に活用するためにコピー操作は必須ではないと思います。たとえば、従来の MutexGuard オブジェクトを考えてみましょう。スタックの自動化に役立つコピー操作は必要ありませんか?

于 2010-12-01T22:45:03.273 に答える
1

C++ の変数は、スタックまたはヒープで宣言できます。C++ で変数を宣言すると、明示的に new 演算子を使用しない限り (ヒープに移動します)、変数は自動的にスタックに移動します。

MyObject x = MyObject(params); // onto the stack

MyObject * y = new MyObject(params); // onto the heap

これは、メモリの管理方法に大きな違いをもたらします。変数がスタックで宣言されると、スコープ外になると割り当てが解除されます。オブジェクトで delete が明示的に呼び出されるまで、ヒープ上の変数は破棄されません。

于 2008-08-27T13:37:36.307 に答える
1

自動スタックは、現在のメソッドのスタックに割り当てられる変数です。スタック自動として機能するクラスを設計する背後にある考え方は、ある呼び出しで完全に初期化し、別の呼び出しで破棄できるようにすることです。デストラクタがオブジェクトによって割り当てられたすべてのリソースを解放し、そのコンストラクタが完全に初期化されて使用できる状態になったオブジェクトを返すことが不可欠です。コピー操作についても同様です。クラスは、完全に機能し、独立したコピーを簡単に作成できる必要があります。

このようなクラスの使用法は、プリミティブな int、float などの使用法に似ている必要があります。それらを定義し(最終的に初期値を与えます)、それらを渡し、最後にコンパイラをクリーニングに任せます。

于 2008-08-27T13:42:05.780 に答える