0

我有我在某个课上写的函数。我不明白为什么当我创建名为: Square square; 的对象时 退出函数时正在调用 Square 的 d'tor。而当我将对象创建为: Square* square = new Square(); 没有 d'tor 被调用。

类上根本没有继承

这里有两个版本的函数示例:

//=======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

当您使用“new”创建对象时,有责任将其删除。这是通过“删除”完成的:

delete square;

在你的第二个函数中,你有一个内存泄漏——对象永远不会被破坏,内存永远不会被释放。

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

这是Square*具有自动存储期限的 a 的定义。该指针在函数结束时自动销毁

但是,指针是用 的结果初始化的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 回答