Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么时候是';删除';对使用“新建”创建的临时对象调用?_C++_New Operator_Delete Operator_Temporary - Fatal编程技术网

C++ 什么时候是';删除';对使用“新建”创建的临时对象调用?

C++ 什么时候是';删除';对使用“新建”创建的临时对象调用?,c++,new-operator,delete-operator,temporary,C++,New Operator,Delete Operator,Temporary,我使用新时间(1,0,0)初始化SmartPtr类 我没有在新时间(1,0,0)上调用delete。一切正常,程序正常运行。但是我很困惑——我应该/不应该在哪里删除时间(1,0,0) 我不理解在这里创建和删除临时对象的概念。 我知道每当我在某个地方写new时,我都必须写delete! 有人能解释一下删除时间(1,0,0)发生在哪里吗 SmartPtr pTime0(新时间(0,0,1))表达式新时间(0,0,1)创建指向堆上永久对象的临时指针。临时指针确实会自动销毁(这是一个no-op),使对象

我使用
新时间(1,0,0)
初始化SmartPtr类

我没有在
新时间(1,0,0)
上调用delete。一切正常,程序正常运行。但是我很困惑——我应该/不应该在哪里删除时间(1,0,0)

我不理解在这里创建和删除临时对象的概念。 我知道每当我在某个地方写
new
时,我都必须写
delete
! 有人能解释一下删除时间(1,0,0)发生在哪里吗


SmartPtr pTime0(新时间(0,0,1))表达式
新时间(0,0,1)
创建指向堆上永久对象的临时指针。临时指针确实会自动销毁(这是一个no-op),使对象仍在堆上,但未被引用。发生了泄漏


为防止泄漏,请确保将指针存储在某个位置,并确保最终对其调用了delete。

我不知道您的
SmartPtr
类的详细信息

在任何情况下,如果您有这样的构造函数:

这是析构函数:

然后使用此代码:

泄漏时间(0,0,1)的一个实例

事实上,您还有一个
new
,而不是
delete
(2个
new
s和1个
delete
):

步骤1:调用
新时间(0,0,1)
并在堆上创建一个新对象。
new
count==1)

步骤2:将此指针传递给
SmartPtr
构造函数,该构造函数深度复制以前创建的对象并在堆上分配新副本,并通过其
\u指针对象
数据成员跟踪此副本。
new
count==2)

步骤3:当
SmartPtr
析构函数运行时,它
delete
s由
\u pointee
数据成员指向的实例,但是您泄漏了在堆上创建的第一个
时间(…)
新时间(0,0,1)

delete
count==1;
new
count==2)

一个可能的修复方法是使用此构造函数:

SmartPtr::SmartPtr(Pointee * p)
    : _pointee(p) // <--- transfer ownerhsip (no deep copies) !
{}
“时间构造函数”
字符串的总计数应与
“时间析构函数”
字符串的总计数相匹配。

有两种修复方法:

方法A,调用方分配,SmartPtr获得所有权:

SmartPtr::SmartPtr(Pointee * p):_pointee(p)
{
}
方法B,调用方提供内容,SmartPtr分配:

SmartPtr::SmartPtr(Pointee v):_pointee(new Pointee(std::move(v)))
{
}
析构函数保持不变:

SmartPtr::~SmartPtr()
{
    delete _pointee; 
}

您可以根据“永不键入新”的原则编写应用程序
将其与现有智能指针相结合,它将成为:

#include <memory>    // this is where the smart-pointers live
#include "Time.h"    // or whatever header defines your "Time" class

int main()
{
    // note that make_shared is essentially a forwarding constructor,
    // give it whatever parameters Time's constructor would take
    auto p = std::make_shared<Time>(0,0,1); 
    // use p here
}
#include//这就是智能指针所在的位置
#包括“Time.h”//或定义“Time”类的任何标题
int main()
{
//请注意,make_shared本质上是一个转发构造函数,
//给它时间构造函数需要的任何参数
自动p=std::使_共享(0,0,1);
//这里用p
}
永远不会有任何泄漏

“永不输入新”应适用于所有应用程序编程, 唯一的例外是,如果你必须写一个低级别 资源管理图书馆

注意,如果一个类进行资源管理,它应该是 唯一的功能


所有其他课程都应遵循

SmartPtr是您设计的课程吗?它可以很好地管理对象生命周期,在这种情况下,类决定何时删除。我不明白为什么要在SmartPtr的ctor中的堆上创建一个新的指针对象。这不是你想要的。您只需编写
\u pointee(p)
,即只需使用给定的相同指针。您的语句将分配一个新的指针对象,并将所提供指针的内容复制到它。我不想
\u指针对象(p)
。如果p(新时间(0,0,1))在我的类之外的其他地方创建,那么它也可以在某个地方被删除(
delete p
),我的SmartPtr析构函数也将
delete _pointee
(由p初始化),因此它将导致运行时错误。我试图实现的概念是在ctor中分配内存,并在dtor中删除它。@Oleksandra:如果类外的代码想要删除
p
本身,那么他们不会使用您的类。他们将该指针与智能指针类关联的原因是,他们希望智能指针为他们执行解除分配。调用者可以通过值传递内容,而不是作为指针,然后您可以动态分配值的副本(希望通过移动),稍后您可以释放该副本。//main.cpp SmartPtr ptTime(新时间(0,0,1));给出以下内容:时间ctor(0,0,1)SmartPtr ctor SmartPtr dtor时间dtor(0,0,1)。为什么程序不中止??如果记录时内存泄漏,也不要忘记复制构造函数。构造函数的数量(无论是复制还是默认还是其他)应该与析构函数的数量相匹配?如果是这样的话,我确实有时间构造函数、时间复制构造函数、SmartPtr构造函数、SmartPtr dtor,并且只有一个时间析构函数@Oleksandra:内存泄漏通常不会中止您的程序,它们只会使您的计算机运行得比需要的慢,而且更慢,并且sl.o.w.e…r。。。。。
SmartPtr::SmartPtr(Pointee * p)
    : _pointee(p) // <--- transfer ownerhsip (no deep copies) !
{}
Time::Time(....)
{
    // Do construction work....

    std::cout << "Time constructor\n";
}

Time::~Time(....)
{
    // Do destructor work....

    std::cout << "Time destructor\n";
}
SmartPtr::SmartPtr(Pointee * p):_pointee(p)
{
}
SmartPtr::SmartPtr(Pointee v):_pointee(new Pointee(std::move(v)))
{
}
SmartPtr::~SmartPtr()
{
    delete _pointee; 
}
#include <memory>    // this is where the smart-pointers live
#include "Time.h"    // or whatever header defines your "Time" class

int main()
{
    // note that make_shared is essentially a forwarding constructor,
    // give it whatever parameters Time's constructor would take
    auto p = std::make_shared<Time>(0,0,1); 
    // use p here
}