Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/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++ 什么时候销毁物品?_C++_Oop_Class_Object - Fatal编程技术网

C++ 什么时候销毁物品?

C++ 什么时候销毁物品?,c++,oop,class,object,C++,Oop,Class,Object,我想确认在以下情况下会发生的行为。假设我将一些函数定义为: std::vector<Object*> FuncA() Result FuncB() FuncA返回的向量何时被销毁(调用其析构函数)?结果是否超出范围?持有对其引用的结果是否会延长其生命周期?如果不是的话,你能解释一下为什么,也许是一种实现我所追求的目标的方法吗 谢谢 编辑:这是结果类 class Result { private: std::vector<Object*>

我想确认在以下情况下会发生的行为。假设我将一些函数定义为:

std::vector<Object*> FuncA()
Result FuncB()
FuncA返回的向量何时被销毁(调用其析构函数)?结果是否超出范围?持有对其引用的结果是否会延长其生命周期?如果不是的话,你能解释一下为什么,也许是一种实现我所追求的目标的方法吗

谢谢

编辑:这是结果类

class Result
    {
    private:
        std::vector<Object*> result;

        void SetData(const Result& other);
        void Free();

        // Constructs the result and takes ownership of the memory.
        Result(const std::vector<Object*>& result);

        Result();

    public:
        Result(const Result& other);
        Result& operator=(const Result& rhs);
        ~Result();

        const Object& operator [] (int index);
    };
类结果
{
私人:
std::向量结果;
无效设置数据(常量结果和其他);
无空洞();
//构造结果并获取内存的所有权。
结果(const std::vector&Result);
结果();
公众:
结果(常数结果和其他);
结果和运算符=(常量结果和rhs);
~Result();
常量对象和运算符[](int索引);
};

如果
结果
包含引用,则您有问题。
FuncA
返回的对象将在
结果
对象返回之前销毁

现在,
Result
按值保存。这意味着
FuncA
的返回值将被复制到构造函数中。当
结果
对象被删除时,向量将被销毁

如果要避免复制,请执行以下操作:

结果(标准::矢量结果)
:结果(标准::移动(结果))
{}
或者,如果您不使用C++11(cf@Steve Jessop的评论)

结果(标准::矢量结果)
{
此->result.swap(结果);
}

这很可能是做你想做的事情的错误方式。当
结果
超出范围时,向量将被销毁。向量中的指针指向的内存不存在

因此,您可以返回一个向量并仍然使用它,但如果该向量副本中的指针被释放,您将遇到UB


使用
std::vector
将为您节省大量麻烦。

请发布
结果的定义。答案取决于存储在内存中的内容。不要使用指针向量,这很容易造成内存泄漏。如果您不想要
std::vector
,至少使用
std::vector
。使用此类的原因之一是为了处理内存问题,它将在销毁时释放所有指针。但是是的,我可能应该使用shared_ptrs:/@user1520427。但是当指针被破坏时释放它可能会给你留下现在无效的那些指针的副本。嗯,这是真的,尽管我打算如何在这个特定的情况下使用它,我不认为我会遇到这个问题。但无论如何,在大多数情况下,应该使用共享PTR吗?什么情况下最好不要使用它们?@user1520427不应该使用
shared\u ptr
的情况是可以使用
unique\u ptr
。在您的情况下,似乎所有权是共享的,这就是为什么我没有首先建议
unique\u ptr
。否则,你应该总是喜欢它们而不是原始的C风格指针。哎呀,这是类定义中的一个输入错误,我本想在构造函数中有一个引用,但不管你回答了我的问题,谢谢。我希望避免先构造向量,然后再将其复制到
Result
,我希望
Result
能够有效地拥有它并延长它的生命周期-而不复制它。@user1520427:您没有显示构造函数的定义,只有声明,所以我们无法判断它是否被复制,我们只能相信你的话。但是,由于
Result
的构造函数采用非常量引用,
Result(FuncA())
的格式根据标准是错误的。MSVC允许它作为一个扩展。另外,该构造函数是私有的,
FuncB
不是朋友,因此它的格式不正确还有第二个原因。除非我误解了,否则这不是真实的代码,所以您可能无法得到关于它的真实答案。@AlexandreC.:从命名构造函数参数(即非临时参数)复制到初始化列表中的数据成员时,是否允许复制省略?也许我遗漏了什么,但我认为不是,所以我认为
Result(std::vector Result):Result(Result){}
必须复制向量。在C++11中,最明显的事情是使用一个右值引用构造函数move来构造数据成员。@SteveJessop代码是基于真实代码的,但我略作删节,只关注问题所在。无论如何,即使我通过引用传入该值,它也会被复制到函数中,所以至少会有一个副本?若我按值传递,可能有两个(一个复制到构造函数中,然后一个复制到成员变量中)?我对什么时候使用引用和什么时候不使用引用(以及什么时候复制东西)感到有点困惑,目前我通常都使用引用,除非它需要在函数中修改。@SteveJessop:这里您使用
std::move
Result(std::vector Result):Result(std::move(Result)){
在任何情况下都能正确执行。复制省略发生在构造函数调用站点。
Result FuncB() {
 ... some stuff here ...
return Result(FuncA())
}
class Result
    {
    private:
        std::vector<Object*> result;

        void SetData(const Result& other);
        void Free();

        // Constructs the result and takes ownership of the memory.
        Result(const std::vector<Object*>& result);

        Result();

    public:
        Result(const Result& other);
        Result& operator=(const Result& rhs);
        ~Result();

        const Object& operator [] (int index);
    };
Result(std::vector<Object*> result) 
    : result(std::move(result))
{}
Result(std::vector<Object*> result) 
{
    this->result.swap (result);
}