改变了一下赋值的顺序,为什么析构函数调用次数就不同了
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的临时对象,只是作为参数在构造函数中。
[解决办法]
Stock myStock=2;
这个是通过调用Stock(double price);来初始化myStock。。并没有创建临时对象。。
myStock = 2;//等价于myStock = Stock(2);先创建一个临时对象。。再赋值给myStock。。
这里多创建了一个对象。。当然析构也多一次。。
都是三个对象,就是赋值顺序不同
第一个才是三个对象。。第二个是四个对象。。第二种情况多了Stock(2)创建的那个临时对象。。你自己看析构函数就知道。。多了一句default name的。。
[解决办法]
第一次直接用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);
[解决办法]
代码里最好加上一个拷贝构造函数,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~
[解决办法]
Stock myStock=2;
这个是通过调用Stock(double price);来初始化myStock。。并没有创建临时对象。。
myStock = 2;//等价于myStock = Stock(2);先创建一个临时对象。。再赋值给myStock。。
这里多创建了一个对象。。当然析构也多一次。。
正解,不理解可以单步调试看,F9+F10+F11
两次都是三个对象,构造函数都调用了三次
担是析构函数调用次数不同
第二种情况析构函数调用了4次,其实构造函数也是调用了4次,生成了4个对象,因为调用了一次Stock(Stock &)这个构造函数,而你么有显式提供这个构造函数,所以没有对应的输出。