[英]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_ptr
和std::shared_ptr
。
Also use std::vector
instead regular C-array也使用std::vector
代替常规 C 数组
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.