Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.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++中的内存管理,我不明白为什么只有一些析构函数在离开作用域时被调用。在下面的代码中,myfunc结束时只调用obj1析构函数,而不是动态分配的obj2 int myfunc (cl1 *oarg) { cout << "myfunc called" << std::endl; cl1 obj1(222,"NY"); cl1 *obj2; obj2= new cl1; oarg->disp(); obj2 -> ~cl1 ; } int myfunc(cl1*oarg){ cout~cl1; }_C++_Scope_Destructor - Fatal编程技术网

离开作用域时未调用析构函数 我正在学习C++中的内存管理,我不明白为什么只有一些析构函数在离开作用域时被调用。在下面的代码中,myfunc结束时只调用obj1析构函数,而不是动态分配的obj2 int myfunc (cl1 *oarg) { cout << "myfunc called" << std::endl; cl1 obj1(222,"NY"); cl1 *obj2; obj2= new cl1; oarg->disp(); obj2 -> ~cl1 ; } int myfunc(cl1*oarg){ cout~cl1; }

离开作用域时未调用析构函数 我正在学习C++中的内存管理,我不明白为什么只有一些析构函数在离开作用域时被调用。在下面的代码中,myfunc结束时只调用obj1析构函数,而不是动态分配的obj2 int myfunc (cl1 *oarg) { cout << "myfunc called" << std::endl; cl1 obj1(222,"NY"); cl1 *obj2; obj2= new cl1; oarg->disp(); obj2 -> ~cl1 ; } int myfunc(cl1*oarg){ cout~cl1; },c++,scope,destructor,C++,Scope,Destructor,这是我的析构函数: cl1 :: ~cl1 () { std::cout<< " cl1 destructor called"<<std::endl; std::cout << this->data << std::endl; //just to identify the obj delete [] str; str = NULL ; }; cl1::~cl1(){ std::cout动态分配的对象是您的责任-您需要明确地清理它们。自动

这是我的析构函数:

cl1 :: ~cl1 () {

std::cout<< " cl1 destructor called"<<std::endl;
std::cout << this->data << std::endl; //just to identify the obj
delete [] str;
str = NULL ;

};
cl1::~cl1(){

std::cout动态分配的对象是您的责任-您需要明确地清理它们。自动对象(例如
obj1
)在这种情况下,在作用域退出之前-显式调用
delete obj2
。注意:此行
obj2->~cl1
-没有任何作用-
delete
将正确触发析构函数

obj2->~cl1;

不要这样做!请改用
delete obj2;

附录
您试图做的是显式调用析构函数。您的代码没有这样做。您的代码获取析构函数的地址,然后将其放入位存储桶。您的代码是禁止操作的。显式调用析构函数的正确方法是
obj2->~cli();

显式调用析构函数通常是不应该做的事情


您应该做的是删除由
new
创建的内存。正确的方法是使用
delete
操作符。这会自动调用析构函数,并释放内存。析构函数不会释放内存。如果分配对象,则未能使用delete会导致内存泄漏。

t使用新的

obj2= new cl1;
然后,除非对其调用
delete
,否则不会隐式调用其析构函数

编辑:作为@David,注释中的含义,可以显式调用对象的析构函数,但根据我的经验,除非使用新版本的new,否则很少需要手动调用析构函数

堆栈上的变量在其作用域结束时被隐式清除(通过调用其析构函数)


动态分配的对象不是隐式清理的,用户有责任显式地调用
delete
清理它们


这正是我们不应该使用原始指针而应该使用智能指针的原因。

对于动态分配的对象,您应该使用
delete

delete obj2;

这将调用析构函数并释放内存。您最好使用智能指针来管理此类对象-它们将为您调用
delete
,即使在
new
delete
之间引发异常,当堆栈上创建的对象停止时,析构函数也会自动调用范围有限


对于动态分配的对象,您需要调用
delete obj
。delete将自动为您调用析构函数。

首先,您应该使用
delete
操作符来析构函数对象,而不是直接调用其析构函数。其次,通过执行
new
操作,您告诉编译器您不想这样做当对象超出作用域时删除该对象。在这种情况下,您需要明确fo
delete objj2;
来删除该对象。

obj1
是类型为
cl1
的对象,具有自动存储持续时间(它在堆栈上分配,其生存期由它所在的作用域决定)


obj1
是类型为
cl1*
的对象。也就是说,它是指针。指针也有自动存储持续时间,但它指向的对象没有。它指向空闲存储中动态分配的对象

当您离开作用域时,具有自动存储持续时间的对象将被销毁。
obj1
将被销毁,并调用析构函数。
obj2
也将被销毁,但是
obj2
不是
cl1
类型,因此它不会调用
cl1
的析构函数。它是一个指针,在它被摧毁了

指针不拥有它们指向的对象,因此它们不做任何事情来确保指向的对象被销毁或清除。(如果您想要“拥有”指针,这就是智能指针类的用途)

考虑到您可以很容易地让多个指针指向同一个对象


如果指针自动删除其指向的对象,则会导致错误。由两个不同指针指向的对象将被删除两次。

使用std::unique\u ptr或std::shared\u ptr代替原始指针。 这是避免内存泄漏或双重释放的最佳方法

这是现代C++中的正确方法。

int myfunc (cl1 *oarg) 
{
    cout << "myfunc called" << std::endl;
    cl1 obj1(222,"NY");
    std::unique_ptr<cl1> obj2( new cl1 );
    oarg->disp();
}
int myfunc(cl1*oarg)
{

显式调用析构函数不会有任何作用,这难道不是真的吗?关键是,在这种情况下不应该这样做case@VJo,非常仔细地看那一行代码,事实上那一行会是一个编译错误…@Nim你是对的。但是如果他能让它编译(正确地调用析构函数)-这样做仍然是错误的。@jalf missing
()
在`~c1'之后,除非您对其调用
delete
,否则它的析构函数将不会被调用,这在技术上是不正确的。您可以手动调用析构函数(问题中的代码几乎正在这样做!):
obj2->~cl1()
(与问题中的代码不同的是调用,即
()
)。请注意,这不会释放内存,但会调用析构函数。Thx很多人,但是我有一个小疑问-如果动态分配的对象没有在函数本身中删除,它可以在函数范围之外使用吗?或者换句话说,每个函数中有一个新的,是否也有一个delete?为什么不调用析构函数释放内存——析构函数中定义了一个delete。哦,等等,它只删除对象的一部分,对吗?是的,动态分配