質問
インターネットを閲覧しているときに見つけたのが、 この郵便受け, 、これにはこれが含まれます
"(よく書かれた)C ++は素晴らしい スタックを自動にするための長さ オブジェクトはプリミティブのように「ちょうどいい」働きをします。 Stroustrup氏のアドバイスに反映されているように、 「intがするようにする」。これには、 オブジェクト指向の原則 発達:クラスが正しくない int のように "動作" するまで、 「3つのルール」に従って、 それができることを保証します(intのように) 作成、コピー、および正しく作成されている スタックとして自動的に破壊されました。
C と C++ のコードを少しだけ実行したことはありますが、重大なことは何もしていません。ただ興味があるのですが、これは正確に何を意味するのでしょうか?
誰か例を挙げてもらえますか?
解決
スタック オブジェクトはコンパイラによって自動的に処理されます。
スコープが終了すると、スコープは削除されます。
{
obj a;
} // a is destroyed here
「新しく追加された」オブジェクトに対して同じことを行うと、メモリ リークが発生します。
{
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
他のヒント
他の回答に加えて:
C++ 言語には実際には auto
キーワードを使用して、オブジェクトのストレージ クラスを明示的に宣言します。もちろん、これはローカル変数の暗黙のストレージ クラスであり、どこでも使用できないため、まったく必要ありません。の反対 auto
は static
(ローカルとグローバルの両方)。
次の 2 つの宣言は同等です。
int main() {
int a;
auto int b;
}
このキーワードはまったく役に立たないため、実際には次の C++ 標準 (「C++0x」) で再利用され、新しい意味が与えられます。つまり、コンパイラーが初期化から変数の型を推測できるようになります。 var
C# の場合):
auto a = std::max(1.0, 4.0); // `a` now has type double.
C++ の変数は、スタックまたはヒープで宣言できます。C++ で変数を宣言すると、明示的に new 演算子を使用しない限り、その変数は自動的にスタックに置かれます (ヒープに置かれます)。
MyObject x = MyObject(params); // onto the stack
MyObject * y = new MyObject(params); // onto the heap
これにより、メモリの管理方法が大きく変わります。変数がスタック上で宣言されている場合、その変数はスコープ外になると割り当てが解除されます。ヒープ上の変数は、オブジェクトに対して明示的に delete が呼び出されるまで破棄されません。
自動スタックは、現在のメソッドのスタックに割り当てられる変数です。自動スタックとして機能するクラスの設計の背後にある考え方は、1 回の呼び出しでクラスを完全に初期化し、別の呼び出しで破棄できる必要があるということです。デストラクターがオブジェクトによって割り当てられたすべてのリソースを解放し、そのコンストラクターが完全に初期化されて使用できる状態になったオブジェクトを返すことが重要です。コピー操作についても同様です。クラスは完全に機能し、独立したコピーを簡単に作成できる必要があります。
このようなクラスの使用法は、プリミティブな int、float などと同様である必要があります。使用されています。これらを定義して (最終的には初期値を与えて)、それらを渡して、最終的にはコンパイラーにクリーニングを任せます。
間違っている場合は訂正してください。ただし、自動スタック クリーニングを最大限に活用するためにコピー操作は必須ではないと思います。たとえば、古典的な MutexGuard オブジェクトを考えてみましょう。スタック自動として機能するためにコピー操作は必要ありません。