Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/440.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++;创建的对象没有新关键字,但构造函数中使用了新关键字_C++ - Fatal编程技术网

C++ C++;创建的对象没有新关键字,但构造函数中使用了新关键字

C++ C++;创建的对象没有新关键字,但构造函数中使用了新关键字,c++,C++,如果我创建一个对象时没有使用诸如“object s(someval)”之类的new关键字,但该对象构造函数使用new,那么当该对象超出范围时,是否会调用析构函数来进行新的分配?我觉得好像是这样,但我不确定。不,如果将动态分配的指针存储为数据成员,则必须在析构函数中显式删除它。这还引入了三个规则(C++11中的五个规则),这是一个麻烦。这就是为什么在可能的情况下应该首选堆栈分配的对象 当需要指针时,对动态分配的数组使用RAII包装,如std::vector,或对单个动态分配的对象使用智能指针,如s

如果我创建一个对象时没有使用诸如“object s(someval)”之类的new关键字,但该对象构造函数使用new,那么当该对象超出范围时,是否会调用析构函数来进行新的分配?我觉得好像是这样,但我不确定。

不,如果将动态分配的指针存储为数据成员,则必须在析构函数中显式删除它。这还引入了三个规则(C++11中的五个规则),这是一个麻烦。这就是为什么在可能的情况下应该首选堆栈分配的对象


当需要指针时,对动态分配的数组使用RAII包装,如
std::vector
,或对单个动态分配的对象使用智能指针,如
std::unique_ptr
std::shared_ptr
。它们为您和您管理内存,无需额外工作。

不,如果您将动态分配的指针存储为数据成员,则必须在析构函数中显式删除它。这还引入了三个规则(C++11中的五个规则),这是一个麻烦。这就是为什么在可能的情况下应该首选堆栈分配的对象

当需要指针时,对动态分配的数组使用RAII包装,如
std::vector
,或对单个动态分配的对象使用智能指针,如
std::unique_ptr
std::shared_ptr
。这些为您和您管理内存,无需额外工作

当该对象超出范围时,是否会调用析构函数来进行新的分配

它取决于
对象的定义方式

如果
new
返回的指针存储在
Object
的某个数据成员中,
delete
Object
本身的析构函数调用,则是,当
s
超出范围时,分配有
new
的对象也将被销毁

否则,否。在丢失对所分配对象的最后一个指针/引用之前,对
new
的每次调用必须与对
delete
的相应调用相匹配,否则将导致内存泄漏

由于这样做很容易失败,而且也很容易错误地取消对悬挂的指针的引用(即指向生命周期已结束的对象),因此通常最好避免通过原始指针、
new
delete
执行手动内存管理(或其数组对应项)

当您需要控制对象的生命周期时,总是更喜欢使用RAII包装器,例如
std::shared_ptr
std::unique_ptr
,除非您确实知道自己在做什么,否则无法执行其他操作

当该对象超出范围时,是否会调用析构函数来进行新的分配

它取决于
对象的定义方式

如果
new
返回的指针存储在
Object
的某个数据成员中,
delete
Object
本身的析构函数调用,则是,当
s
超出范围时,分配有
new
的对象也将被销毁

否则,不。每次调用
new
都必须与相应的调用
delete
相匹配,然后才能丢失对所分配对象的最后一个指针/引用,否则将导致内存泄漏

由于这样做很容易失败,而且也很容易错误地取消对悬挂的指针的引用(即指向生命周期已结束的对象),因此通常最好避免通过原始指针、
new
delete
执行手动内存管理(或其数组对应项)

当您需要控制对象的生命周期时,总是喜欢使用RAII包装器,例如
std::shared_ptr
std::unique_ptr
,除非您真的知道自己在做什么,否则无法执行。

不,它不会。。。 您必须在使用
new
分配的对象的析构函数中定义
delete
。 您使用
new
在堆上创建一个对象,当您的对象被销毁时,您将丢失对创建内存泄漏的对象的引用。 为了避免这种情况,您可以使用智能指针,如
shared\u ptr

不,它不会。。。 您必须在使用
new
分配的对象的析构函数中定义
delete
。 您使用
new
在堆上创建一个对象,当您的对象被销毁时,您将丢失对创建内存泄漏的对象的引用。
为了避免这种情况,您可以使用智能指针,如
shared\ptr
否您必须在析构函数中为该对象显式调用delete

否您必须在析构函数中为该对象显式调用delete

让我们给对象命名,好吗

struct A {
    A() b(new B) {}
    B* b;
    C c;
};

A a;
在这里,
a
的析构函数被调用。
a::c
的析构函数也被调用(当
a
被析构函数时自动调用)


但是,
*A::b
的析构函数未被调用
–实际上,指针对象
A::b
本身已被正确释放,但由于它是一个基本类型(它是指针!),因此不会发生任何事情。但是,指针对象
*A::b
需要手动析构函数(并释放内存)通过调用
delete

让我们为对象命名,好吗

struct A {
    A() b(new B) {}
    B* b;
    C c;
};

A a;
在这里,
a
的析构函数被调用。
a::c
的析构函数也被调用(当
a
被析构函数时自动调用)

但是,
*A::b的析构函数不是调用的