0

私はいくつかのクラスで書いた関数を持っています。Square square; という名前のオブジェクトを作成するときの理由がわかりません。関数を終了するときに Square の d'tor が呼び出されています。オブジェクトを次のように作成するとき: Square* square = new Square(); d'tor は呼び出されていません。

クラスには継承がまったくありません

2 つのバージョンの関数の例を次に示します。

//=======Enter to d'tor in the end of the function to ~Square==========
void DrawShapesApp::addSquare()
{
    int row, col;
    int edge;
    char ch;

    Square square;

    getSquareInfo(row, col, edge, ch);
    square.setAll(row, col, edge, ch);
    m_squares.push_back(&square);
}





//=======Doesn't enter to d'tor in the end of the function==========
void DrawShapesApp::addSquare()
{
    int row, col;
    int edge;
    char ch;
    Square* square = new Square();

    getSquareInfo(row, col, edge, ch);
        (*square).setAll(row, col, edge, ch);
    m_squares.push_back(&square);
}
4

4 に答える 4

2

「新規」でオブジェクトを作成する場合、それを削除するのはあなたの責任です。これは「削除」で行われます。

delete square;

2番目の関数では、メモリリークが発生します。オブジェクトが破棄されることはなく、メモリが解放されることもありません。

于 2013-03-23T21:23:25.310 に答える
1
Square* square = new Square();

これは、Square*自動保存期間の定義です。そのポインタ、関数の終了時に自動的に破棄されます。

ただし、ポインタはの結果で初期化されますnew Square()。この新しい式は、動的な保存期間Squareを持つタイプのオブジェクトを作成します。そのオブジェクトは、関数の終了時に破棄されません。

動的な保存期間を持つオブジェクトを破棄するには、deleteそのオブジェクトへのポインターを呼び出す必要があります。この場合、次のようにします。

delete square;

オブジェクトを手動で破棄しないと、メモリリークが発生します。

ただし、最近のC ++では、動的に割り当てられたオブジェクトを、次の処理を行うスマートポインターで管理するのが一般的deleteです。

std::unique_ptr<Square> square(new Square());
于 2013-03-23T21:23:22.690 に答える
1

この方法で作成されたオブジェクト:

Square square;

自動保存期間があると言われ、範囲外になると自動的に破棄されます。例えば:

void foo()
{
    Square square1;
    {
        Square square2;
    } // Here square2 will be destroyed

    if (cond) { /* .... */ }
    else
    {
        Square square3;
        // ...
    } // Here square3 will be destroyed
    // ...
} // Here square1 will be destroyed

オブジェクトがスコープの終わりを生き残る必要がない/望まない場合は、通常、この方法でオブジェクトをインスタンス化することを選択します(ただし、C ++ 11でオブジェクトを移動すると、自動保存期間のあるオブジェクトでもこれを実現する方法が提供されると主張できます) 。

一方、この方法で作成されたオブジェクトは次のとおりです。

Square* pSquare = new Square();

動的な保存期間があると言われdelete、そのオブジェクトへのポインタに対して呼び出されると破棄されます。

delete pSquare;

この場合、オブジェクトを手動で破棄する責任があり、割り当てられたすべてのオブジェクトに対して破棄しないとnewメモリリークが発生します。例えば:

void foo()
{
    Square* pSquare1 = new Square();
    Square* pSquare2 = nullptr;
    if (/* ... */)
    {
        pSquare2 = new Square();
    }

    delete pSquare2; // Here the object pointed to by pSquare2 is destroyed
} // Whoops! I forgot deleting the object pointed to by pSquare1, that's a leak!

通常、オブジェクトをスコープの終わりを超えて存続させたい場合、および/または参照セマンティクスが必要な場合は、この方法でオブジェクトを作成することを選択します。

于 2013-03-23T21:24:10.610 に答える
0

このようなオブジェクトを宣言すると

Square square;

宣言範囲外になると自動的に破棄されます。

と...

このようなオブジェクトを宣言すると

Square *square = new Square();

後に破棄されdeleteます。オブジェクトを明示的に削除する必要があります。

于 2013-03-23T21:23:47.187 に答える