读书人

改变了一下子赋值的顺序为什么析构函

发布时间: 2013-08-09 15:16:24 作者: rapoo

改变了一下赋值的顺序,为什么析构函数调用次数就不同了

Stock.cpp


#include "Stock.h"
#include <string>
#include <iostream>

using namespace std;

Stock::Stock(string name, double price) {
cout << "with param constractor" << endl;
Stock::m_name = name;
Stock::m_price = price;

}

Stock::Stock(double price) {
Stock::m_name = "defautl name";
Stock::m_price = price;
cout << "with param constractor" << endl;
}

Stock::Stock() {
cout << "with no param constractor" << endl;
}

Stock::~Stock() {
cout << "destory stock name:" << Stock::m_name << " ByeBye!" << endl;
}



Stock.h

#ifndef STOCK_H_
#define STOCK_H_

#include <string>
#include <iostream>

using namespace std;

class Stock {

private:
string m_name;
double m_price;

public:
Stock::Stock();
Stock::Stock(double price = 0.0);
Stock::Stock(string name = "defalut name", double price = 0.0);
virtual ~Stock();
};

#endif /* STOCK_H_ */


main调用的如果是

Stock myStock=2;
myStock=Stock("a",1.0);
myStock=Stock("abcde",3.0);


则打印:
with param constractor
with param constractor
destory stock name:a ByeBye!
with param constractor
destory stock name:abcde ByeBye!
destory stock name:abcde ByeBye!

析构函数调用三次!

main调用的如果是

Stock myStock=Stock("a",1.0);
myStock=2;
myStock=Stock("abcde",3.0);


则打印:
with param constractor
destory stock name:a ByeBye!
with param constractor
destory stock name:defautl name ByeBye!
with param constractor
destory stock name:abcde ByeBye!
destory stock name:abcde ByeBye!

析构函数调用四次!


那为什么第一个少一次呢?


[解决办法]
第一次直接用2来初始化对象。
第二次是用2构造了一个临时对象。调用的复制构造函数构造临时对象。然后再用析构函数析构
[解决办法]

Stock myStock=2;

这个是通过调用Stock(double price);来初始化myStock。。并没有创建临时对象。。

myStock = 2;//等价于myStock = Stock(2);先创建一个临时对象。。再赋值给myStock。。

这里多创建了一个对象。。当然析构也多一次。。
[解决办法]
因为没有生成2的临时对象,只是作为参数在构造函数中。


引用:
Quote: 引用:

第一次直接用2来初始化对象。
第二次是用2构造了一个临时对象。调用的复制构造函数构造临时对象。然后再用析构函数析构


myStock = 2; 这个对象后来被销毁了,
因为myStock=Stock("a",1.0);
那为什么没有调用2这个对象的析构函数呢

[解决办法]
引用:
Quote: 引用:

Stock myStock=2;

这个是通过调用Stock(double price);来初始化myStock。。并没有创建临时对象。。

myStock = 2;//等价于myStock = Stock(2);先创建一个临时对象。。再赋值给myStock。。

这里多创建了一个对象。。当然析构也多一次。。


都是三个对象,就是赋值顺序不同

第一个才是三个对象。。第二个是四个对象。。第二种情况多了Stock(2)创建的那个临时对象。。你自己看析构函数就知道。。多了一句default name的。。
[解决办法]
引用:
Quote: 引用:

第一次直接用2来初始化对象。
第二次是用2构造了一个临时对象。调用的复制构造函数构造临时对象。然后再用析构函数析构


myStock = 2; 这个对象后来被销毁了,
因为myStock=Stock("a",1.0);
那为什么没有调用2这个对象的析构函数呢

对象生命周期还没结束,只是值发生了变化
[解决办法]
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

[解决办法]
引用:
Stock myStock=2;

这个是通过调用Stock(double price);来初始化myStock。。并没有创建临时对象。。

myStock = 2;//等价于myStock = Stock(2);先创建一个临时对象。。再赋值给myStock。。


这里多创建了一个对象。。当然析构也多一次。。

正解,不理解可以单步调试看,F9+F10+F11
[解决办法]
代码里最好加上一个拷贝构造函数,Stock::Stock(Stock & s);
[解决办法]
引用:
Quote: 引用:

代码里最好加上一个拷贝构造函数,Stock::Stock(Stock & s);



---------------------------------------情况1
Stock myStock = 2;
myStock = Stock("a", 1.0);

normal 1 没有临时对象产生
normal 2
destory stock name:a ByeBye! 临时1对象删除
destory stock name:a ByeBye!



---------------------------------------情况2
Stock myStock = Stock("a", 1.0);
myStock = 2;

normal 2
copy stock name:a
destory stock name:a ByeBye! 临时1对象删除
normal 1
destory stock name:defautl name ByeBye! 临时2对象删除(为什么会产生临时2对象呢)
destory stock name:defautl name ByeBye!



myStock = 2; 将调用 Stock(double price);这个构造函数生成一个临时的Stock对象,然后将它赋值给myStock, 无法将double的值直接赋给Stock的对象,类型不匹配。
[解决办法]
个人觉得最好就是看下反汇编的代码直接debug!

第一次之所以才析构3次,因为开始用2直接复制,编译器并没有为你创建一个临时的对象
第二次出现4次是应该,一开始mystroke已经存在指向了,所以当用2进行赋值时候,编译器可能做的工作是为2创建一个临时的stroke对象然后将该对象赋值给mystroke,所以就有了上面的结果了

PS:不能确定是否理解正常,因为没有实地debug~
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Stock myStock=2;

这个是通过调用Stock(double price);来初始化myStock。。并没有创建临时对象。。

myStock = 2;//等价于myStock = Stock(2);先创建一个临时对象。。再赋值给myStock。。

这里多创建了一个对象。。当然析构也多一次。。

正解,不理解可以单步调试看,F9+F10+F11


两次都是三个对象,构造函数都调用了三次
担是析构函数调用次数不同


第二种情况析构函数调用了4次,其实构造函数也是调用了4次,生成了4个对象,因为调用了一次Stock(Stock &)这个构造函数,而你么有显式提供这个构造函数,所以没有对应的输出。

读书人网 >C++

热点推荐