企业网站seo方案,婚庆公司租车,百度竞价推广什么意思,哪个网站可以做中文云文字事情是这样的#xff1a;博主今天回看以前实现过的string#xff0c;当时就遇到了一个bug:可见博主当时的破防。因为最近在集中复盘C初阶部分#xff0c;就有点好奇年轻的时候自己写的模拟string是什么样。没想到给我自己留了个bug。现在来细看这个场景#xff1a;为了测试…事情是这样的博主今天回看以前实现过的string当时就遇到了一个bug:可见博主当时的破防。因为最近在集中复盘C初阶部分就有点好奇年轻的时候自己写的模拟string是什么样。没想到给我自己留了个bug。
现在来细看这个场景为了测试自己写的赋值拷贝现代写法效果有了这个函数。void test11(){//现代构造的写法string s(helloworld);string s2(s);// 现代拷贝构造cout s2 endl;string s3(cherry magic);s2 s3;// 现代赋值拷贝cout s2 endl;}
当来到165行时——即我打算让s3赋值给现有的对象s2此时自然要调用我亲手写的赋值拷贝。图1 调试到165行图2 亲手写的赋值拷贝当我按F11企图跳进operator里时却是来到了拷贝构造这里。嗯此举何意啊——正常意料我亲手写的赋值拷贝operator传的参数是传值传参传值自定义类型string传参都要雷打不动先拷贝构造一份图2 继续下一步,来到了string的拷贝构造函数没错拷贝构造我也写出了现代写法——避免这里长篇大论现代写法我几句话说个大概说不定读者看完就能上手写。
string tmp(s.c_str());//tmp建立在当前函数栈上等当前函数结束函数栈帧被销毁生命周期也结束了。当这句话执行完tmp就是存在于当前栈上但内容是拷贝s的string对象。我们拷贝构造函数的目的就是让当前的*this未构造的对象拷贝传入对象s的内容完成对象初始化。无论如何当拷贝构造函数结束*this是完全实例化tmp却要走向独属它的落幕因为tmp是string自定义类型对象,它自动会调用析构完成资源释放。tmp拷贝完了*this还没拷贝。怎么办把*this有个大胆的想法——
swap(tmp);// 完整写 this-swap(tmp); 或者 (*this).swap(tmp);看我的批注*this用自己的成员函数将tmp和自己交换——交换了拷贝的内容。*this就这么轻轻一换完成了拷贝构造tmp就拿着本来无用的信息去析构了。
我们继续按F11,等此次拷贝构造结束——跳入operator的参数就构造完成我们就进入operator看看问题出在哪。图3先拷贝构造图4string tmp(s.c_str())已然完成图5*this拷贝构造完成tmp此时该走向独属于它的落幕——身为string家中的长(栈子它有自己的使命*this是次子(bushi图6tmp开始析构图7首先析构的——tmp的成员变量_str指向堆上的资源图8报错了牛其实刚刚那一步可能有读者看出不对劲了。tmp交换过来的内容应该是完全没被初始化的——怎么可能会有需要的释放的资源那个_str也是生得奇怪——恰好是随机值躲过了判空检查所以避无可避地执行了delete[] _str;我今天在改这个代码的时候其实没注意到这点因为出了构造函数完成了参数的拷贝构造我想着此时该进入operator了。直接按下了F10——跳过了tmp的析构直接出现了这一幕。所以下意识判断是operaor的问题这也是为什么我会当时写下这句判断——图9看得出来年轻时候第一次写现代写法很没底气。一报错就怀疑上了真相是什么今天在改代码的时候我发现因为*this天生生得潦草_str这个指针怎么生都是随机值——所以tmp换到它的内容必走析构里的delete[] _str;——这件事让我很是苦恼知道哪里出问题了却是下不了手。有没有什么方法有的只是我忘了我忏悔初始化列表我今天也是开眼了拷贝构造也是构造。只要是构造函数类型的成员变量就会走初始化列表——初始化列表存在的意义就是对成员变量定义。身为变量有了声明自然要有定义。所以不管显示写初始化列表与否成员变量都会被定义即成员变量都会走初始化列表。初始化列表是很客观的存在不是我们不写就不存在的。如果显示写初始化列表相应成员变量都会被规定的值初始化
如果不显示写可以在声明的位置给出缺省值——没错这里的缺省值就是给未显示写在初始化列表的成员进行定义如果声明都不给缺省值了那编译器表示“那我随意了”——对于内置类型编译器会给它随机值取决于编译器行为不确定对于自定义类型会去调用它的默认构造如果没有默认构造会编译报错想起来了我再看我的string成员变量声明——果然没有声明值而且刚刚的拷贝构造也没显示初始化列表完美地避开正确初始化机会图10string类的成员变量声明图11加上缺省值静态成员变量在其他地方定义了再看效果图12成功运行我发现AI摘要比我写得完整但我想没我写得有趣对只是我想
摘要博主复盘自己早期实现的string类时发现了一个隐藏bug。问题出现在拷贝构造函数的现代写法中当交换临时对象tmp和未初始化的*this时由于未显式初始化_str成员变量导致析构时delete了一个随机地址。通过给成员变量添加缺省值解决了这个因未初始化引发的未定义行为。文章详细记录了调试过程揭示了C构造函数初始化列表的重要性以及显示初始化成员变量的必要性。最终修复方案是为string类的成员变量添加了缺省值声明使程序得以正确运行。