[问题] class destructor

楼主: s5031588 (好马儿)   2017-10-08 20:45:23
▉▂开发平台(Platform): (Ex: Win10, Linux, ...)
MacOSX
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
g++5.4
问题(Question):
大家好,最近在修资料结构这门课,过去虽然有修过计算机程式
,但是两学分的课所以感觉学得不是很扎实,对于class的部分只有粗略带过..
所以来这边请教大家:
对于一个data member中含有pointer的class,初始时会用new配置内存,
而自行建立的destructor会用delete释放配置给该指标的内存,请问这样的状况下
该怎么在member function中回传一个local的class变量呢?
因为函数功能的需要,必须在函数中宣告一个class变量a来承接运算的结果,并return
该变量给calling function,由calling function中的class变量b承接,但是这样的情
况下,由于member function terminates, destructor将a里面的pointer给delete掉,
造成calling function中b里面的指标指向一个直随时有可能被修改的地方...
有自己试着去overload operator=及建立copy constructor来看看是否可以让calling
function 中b里面的pointer指向一个新的地方,在复制a的值过去,但好像a会先被
destructed(?!)..
上网查了很多destructor, return object的关键字,都找不到想要的答案..
在这里麻烦大家解答了..
在下面附上class 的程式码,大致上是我在建立一个stack的class 有一个destructor:
~Stack(){delete [] stack
初始的constructor有用new给该指标动态配置内存
问题卡在是我要写一个member function splitStack(),作用是要将某个stack从中间
某个点分开拆成两个stack,所以这个function 必须return stack型态的variable,
但是splitStack()中宣告的first再回传值给main后,就被解构了..
程式码(Code):(请善用置底文网页, 记得排版)
http://codepad.org/IjGU1cDW
作者: jerryh001   2017-10-08 21:07:00
是要定义copy constructor没错 看看有没有哪里写错发现个奇怪的地方 destructor不应该手动呼叫
楼主: s5031588 (好马儿)   2017-10-08 22:07:00
请问j大 copy constructor该怎么写呢?因为我造我的逻辑写还是没办法欸..附上我copy constructor的程式码:http://codepad.org/hP4cyP6b顺便附上main的程式码http://codepad.org/TcOdcyCc我用一步步执行发现,虽然copy function不会让两个POINTER 直接相等,但是splitStack一结束,居然会两个指标都destruct...= =,有人可以解释原理吗QQ
作者: jerryh001   2017-10-08 22:40:00
operator=也要留吧copy ctor 的参数也许也要<T>吗? 有点忘了
作者: stucode   2017-10-08 23:20:00
怎么写完 copy ctor 后 operator = 就不见了XD?1. copy constructor 里面不用 delete,因为是初始化,还没有前值,直接 new 然后 copy 就好。2. copy assignment 需要检查并释放(或重新利用)现有资源,同时要避免 self-assignment 造成错误的delete。3. copy assignment 请传回 reference,不要传值。4. splitStack() return first 就好,不用再包一层。其实你的指标几乎都是在 3. 或 4. 多余的临时物件中被delete 掉的。不过如果有做好 deep copy,顶多就是多跑几次 copy 效能较差而已,也不至于会使用到被 delete掉的指标,造成严重错误。
作者: lc85301 (pomelocandy)   2017-10-09 01:04:00
传回reference 是要允许使用 move 来减少一次 copy 吧
作者: stucode   2017-10-09 05:57:00
传回值的话,比较容易产生不必要的临时物件。除此之外,还可能导致非使用者预期的行为。其实 C++ 并没有硬性规定 copy assignment 要传回 reference。这比较像是一种惯例,让自定义类别的行为尽可能相似于 C++ 原生型别(如 int)的行为。减少类别使用时产生意料之外的效果。另外一个理由是,CopyAssignment requirements 要求回传型态必须是 T&,没有满足这个条件可能无法正常使用某些标准容器的方法。事实上,如果没有为类别宣告这个函数,编译器自动帮你生成的版本也是传回 reference。当然,如果你有更好的理由传回新物件或者是其他型别,那就不用客气的传吧!只要确保使用者了解并正确使用你的类别即可。
作者: james732 (好人超)   2017-10-09 10:02:00
顺便学一下什么是rvalue reference与move吧XD
作者: Caesar08 (Caesar)   2017-10-09 13:50:00
如果你想要预先allocate一些memory来用,你需要知道placement new才行。今天destructor没问题是因为T是int建议先看gcc或msvc的vector怎么实作vector,再实作stack
作者: stucode   2017-10-09 20:09:00
实测了一下,解构都正常喔。如果你有开最佳化(或者是IDE 的 Release mode),那 first 可能被 RVO 掉,实际解构会在 b 生命周期结束时(离开 main() 时)发生。另外,复制建构函数里的 new 括号错了。

Links booklink

Contact Us: admin [ a t ] ucptt.com