对象copy时的根本不存在写时复制(自己的疏忽大意。。。

昨天在实验深浅拷贝时发现了一个现象,由于代码写的有问题导致了自己得出了一个错误的结论(认为对象拷贝时也存在写时拷贝),得出结论之后为了验证自己猜想的正确性,又经过查资料发现并没有人提出这个问题,以为自己发现了一个重大的秘密,也就想着把发现记录下来装装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++是需要不断练习的。

看书的过程中一定要多动手写代码,写完代码之后尽可能的写博客记录学习过程,这样能让自己得到真正的学习,并及时发现自己的错误(这次犯傻发现的错误结论,差点让我到知乎上对大佬提问,想想那种画面都可怕【自己的错误还真的以为自己发现了新天地】。。。。。。。。。。。。

结束,原创,欢迎指正。。。。


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sky_s_limit/article/details/80321533
个人分类: C/C++
上一篇C++虚继承内存探索(编译背着我们做了什么???
下一篇写时拷贝(stl string类与自实现小例子。。。
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭