昨天在实验深浅拷贝时发现了一个现象,由于代码写的有问题导致了自己得出了一个错误的结论(认为对象拷贝时也存在写时拷贝),得出结论之后为了验证自己猜想的正确性,又经过查资料发现并没有人提出这个问题,以为自己发现了一个重大的秘密,也就想着把发现记录下来装装B,但是在写博客的过程中,我竟然发现此结论是自己的代码错误所导致,有种瞬间打脸的感觉,但也有所学习,对代码是用来写的有了更深刻的认识。。。。。。。
(经过查资料,发现C++的string类在copy时是存在写时拷贝的,重要知识点。。。。。。。。。)
以下是自己犯蠢的经过:(问题出在new分配动态内存的语句所处的代码位置,先指出问题
str = new int; 这段代码才是关键
直接上代码了。。
代码一:
#include<iostream>
using namespace std;
class String{
private:
int *str;
public:
int getStr(){
cout<<str<<endl;
return *str;
}
void setStr(int s){
str = new int;
*str = s;
}
~String(){
delete str;
}
};
int main(){
String str;
int a = 5;
str.setStr(a);
cout<<str.getStr()<<endl;
String b;
b = str;
cout<<str.getStr()<<endl;
return 0;
}
运行结果如下:
对象b经过拷贝,使str成员变量与对象str的str指向同一内存地址,同时在程序结束运行时分别对两个对象进行析构时,由于0x81a1008地址被析构两次而出错,这就是所谓的浅拷贝。(到这还是没问题的)
对上述代码稍加修改:
代码二:
#include<iostream>
using namespace std;
class String{
private:
int *str;
public:
int getStr(){
cout<<str<<endl;
return *str;
}
void setStr(int s){
str = new int;
*str = s;
}
~String(){
delete str;
}
};
int main(){
String str;
int a = 5;
str.setStr(a);
cout<<str.getStr()<<endl;
String b;
b = str;
cout<<b.getStr()<<endl;
b.setStr(10);
cout<<str.getStr()<<endl;
cout<<b.getStr()<<endl;
return 0;
}
上述代码将对象str拷贝到b上之后,再对b调用setStr()修改了对象中成员变量str指向的值,结果如下:
这就是我代码出错导致的结果,在setStr()函数中重新申请了str所指向的内存,所以程序结束进行析构时,不会出现代码一的错误
实验浅拷贝的正确代码在下面:
代码三:
#include<iostream>
using namespace std;
class String{
private:
int *str;
public:
String(){
str = new int;
}
int getStr(){
cout<<str<<endl;
return *str;
}
void setStr(int s){
*str = s;
}
~String(){
delete str;
}
};
int main(){
String str;
int a = 5;
str.setStr(a);
cout<<str.getStr()<<endl;
String b;
b = str;
cout<<b.getStr()<<endl;
b.setStr(10);
cout<<str.getStr()<<endl;
cout<<b.getStr()<<endl;
return 0;
}
此时的运行结果如下:
结果与代码一情况相同,此段代码将动态内存申请放在了String类的构造函数中,进行对象拷贝时,所拷贝的对象b的str成员变量与对象str的成员变量str指向相同的地址,即造成了浅拷贝问题,析构出错。
同时,这也是一个浅拷贝的例子。。。。。。。
此次经历差点由于自己的错误得出错误的结论,但好在及时的发现了问题,也印证了一句话:C++是需要不断练习的。
看书的过程中一定要多动手写代码,写完代码之后尽可能的写博客记录学习过程,这样能让自己得到真正的学习,并及时发现自己的错误(这次犯傻发现的错误结论,差点让我到知乎上对大佬提问,想想那种画面都可怕【自己的错误还真的以为自己发现了新天地】。。。。。。。。。。。。
结束,原创,欢迎指正。。。。