临时对象未正确销毁?

T.J*_*.J. 1 c++ memory-management temporary-objects

在这里查看此代码:

class test
{
    int n;
    int *j;
public:
    test(int m)
    {
        n = 12;
        j = new int; 
        cin >> *j;
    }

    void show()
    {
        cout << n << ' ' << *j << endl;
    }

    ~test()
    {
        delete j;
    }

};

int main()
{
    test var = 123;
    var.show();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这个程序中,编译器应该抱怨双重删除j.首次删除是在temporary(123)销毁临时对象时完成的.第二次删除是在var销毁对象时完成的.但这工作正常吗?

这是否意味着临时对象不会调用析构函数?

Tha*_*tos 8

有争议的是这样的:

test var = 123;
Run Code Online (Sandbox Code Playgroud)

我相信,相关的标准文本(评论中的专家正在引用)是(8.5,"声明者"):

选择的函数以初始化表达式作为参数调用; 如果函数是构造函数,则调用初始化目标类型的cv-unquali fi ed版本的临时版本.临时是一个右值.然后,根据上面的规则,调用的结果(对于构造函数的情况是临时的)用于直接初始化作为复制初始化目标的对象.在某些情况下,允许实现通过将中间结果直接构造到正在初始化的对象中来消除此直接初始化中固有的复制 ;

实际上,在12.6中,我们得到了一个例子:

complex f = 3;  // construct complex(3) using
                // complex(double)
                // copy it into f
Run Code Online (Sandbox Code Playgroud)

因此,在您的使用中=,您的实现可能是直接构造对象并完全消除中间临时(并且,正如评论所指出的,大多数都是这样).

此类不能正确复制,因此创建它的副本(以及释放副本和原始文件)将导致双重删除(以及崩溃,未定义的行为等).由于未创建副本,因此上述情况不会发生.

  • 这是错的.标准的字母表示创建临时对象并将其复制到最终对象.但是,允许编译器忽略副本(他们也可以在其他情况下这样做).我所知道的所有编译器都会删除副本,但复制构造函数仍然可以访问. (4认同)