简体   繁体   English

C++ 析构函数在 scope 的生命周期之前调用

[英]C++ destructor called before lifetime of scope

I have a question about triggering a destructor for an object prematurely.我有一个关于过早触发 object 的析构函数的问题。 I have an dynamically allocated array of pointers to dynamically allocated Word objects.我有一个动态分配的指针数组,指向动态分配的 Word 对象。 The name of the array is words_.数组的名称是 words_。 words_ is a class attribute of another class called Dictionary. words_ 是另一个名为 Dictionary 的 class 的 class 属性。

In my Dictionary class, I have a function where I access each Word object and call a member function of the Word class. In my Dictionary class, I have a function where I access each Word object and call a member function of the Word class.

The below code triggers the destructor prematurely:下面的代码过早地触发析构函数:

Word *curr_word_ptr = words_[idx]; // This line is okay, doesn't trigger destructor
Word curr_word = *curr_word_ptr; // This line triggers the destructor prematurely
curr_word.callMemberFunc();

Because of the second line, as soon as the scope of the function ends, the destructor is called.因为第二行,只要 function 的 scope 结束,就会调用析构函数。

But if I access it through the array indices alone:但是,如果我仅通过数组索引访问它:

*(words_[idx]).callMemberFunc(); // The desctructor is not called prematurely

Is the problem because I have a stack variable (not even a stack pointer variable) accessing a dynamically allocated object?问题是因为我有一个堆栈变量(甚至不是堆栈指针变量)访问动态分配的 object 吗? Thus, when the scope of the function ends, both the stack variable (curr_word) and the dynamically allocated stack object gets destroyed?因此,当 function 的 scope 结束时,堆栈变量(curr_word)和动态分配的堆栈 object 都被破坏了吗?

Thank you.谢谢你。

Word curr_word = *curr_word_ptr; defines a local Word , that only lives in the local scope, your function.定义了一个本地Word ,它只存在于本地 scope,即您的 function 中。 When the function exits, it is destroyed.当 function 退出时,它被销毁。 Note it is a copy of the initial Word that is destroyed, not the original.请注意,被销毁的是初始Word的副本,而不是原始 Word。

If you want handy syntax so you don't have to dereference all over, or make a copy, use a reference:如果您想要方便的语法,这样您就不必全部取消引用或复制,请使用参考:

Word &word = *curr_word_ptr;

This is the syntactic sugar C++ provides to refer to an object without pointers (directly).这是语法糖 C++ 提供来引用没有指针的 object(直接)。 Note though, any changes made to word will affect your original word as well in this case.但请注意,在这种情况下,对word所做的任何更改也会影响您的原始单词。

The problem is even worse if your Word s contains dynamically allocated memory.如果您的Word包含动态分配的 memory,则问题会更加严重。 Assuming you use the default copy constructor, the addresses will be copied.假设您使用默认的复制构造函数,地址将被复制。 As such, destruction of a local Word will free memory still referenced by the original Word , causing a crash when next accessed.因此,销毁本地Word将释放 memory 仍由原始Word引用,从而在下次访问时导致崩溃。

Word curr_word = *curr_word_ptr;

creates on stack copy of the object and that copy gets destroyed.在 object 的堆栈副本上创建并且该副本被销毁。

Most probably you class has missing a logic and you need define copy constructor to prevent crashes or disable copy constructor so you can create copy by mistake like here.很可能您 class 缺少逻辑,您需要定义复制构造函数以防止崩溃或禁用复制构造函数,以便您可以像这里一样错误地创建副本。

*(words_[idx]).callMemberFunc();

Invokes method directly on object pointed by object stored in array.直接在存储在数组中的 object 指向的 object 上调用方法。 Copy is not created.未创建副本。

Other way you can write this line:其他方式你可以写这一行:

words_[idx]->callMemberFunc();

I see also a problem since you are using raw pointers.我也看到了一个问题,因为您使用的是原始指针。 Since c++11 this approach is considered bad practice.由于 c++11 这种方法被认为是不好的做法。 Learn to use std::uniqie_ptr and std::shared_ptr .学习使用std::uniqie_ptrstd::shared_ptr

Also use std::vector instead regular C-array也使用std::vector代替常规 C 数组

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM