C++String的实现-创新互联
String的实现需要注意的是String的拷贝构造。它的拷贝构造有深拷贝和浅拷贝之分。
公司主营业务:网站设计制作、做网站、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联建站是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联建站推出咸阳免费做网站回馈大家。我们先来用浅拷贝实现String
class String { public: String() { str = new char('A'); } String(char *s) { str = new char[strlen(s) + 1]; if (str != NULL) { strcpy(str, s); } } String(const String& s) { str=s.str; } String& operator=(const String& s) { if (this != &s) { str=s.str; } return *this; } private: char *str; }; void test() { String s1("hello world"); String s2(s1); }
当s1,s2出自的作用域时,会自动调用析构函数,此时s1,s2指向同一片内存。所以这块内存会被释放两次,程序会崩溃。
所以在这里我们要采用深拷贝的方式
构造函数和赋值运算符重载
String(const String& s) { str = new char[strlen(s.str) + 1]; //new出来一块新的空间 if (str) { strcpy(str, s.str); } } String& operator=(const String& s) { if (this != &s) { if (str != NULL) { delete[] str; str = new char[strlen(s.str) + 1]; strcpy(str, s.str); } } return *this; }
还有一种方法可以解决这个一块空间会被多次释放的问题,那就是写时拷贝
在第一次构造一个对象的时候,多开辟四个字节当做计数器,用来记录有几个指针指向这块空间。每当用这块空间拷贝构造一个新对象或者把这块空间赋给另外一个对象时,计数器相应增加。那么当调用析构函数时,每次计数器减一,当计数器减到一时,说明只有一个指针指向这块空间,此时再把这块空间delete,就不会出现一块空间多次释放的问题了。
class String { public: String(char *str="") :_str(new char[strlen(str)+1+4]) { *((int *)_str) = 1; //将开辟的空间前4个字节强制转换成整型并赋为1 _str = _str + 4; //将_str重新定为真正字符串开始的地方,这样比较方便 strcpy(_str, str); //不用每次向后找 } String(const String& str) { _str = str._str; (*((int *)(_str - 4)))++; } ~String() { if (*_str != NULL) { if (((*((int *)(_str - 4)))--) == 0) //判断计数器是否减到0 { delete[] (_str-4); } } } public: String& operator=(const String& str) { if (this != &str) { if (((*((int *)(_str - 4)))--) == 0) { delete[] (_str-4); } _str = str._str; (*(int *)(str._str - 4))++; return *this; } } char& operator[](int index) { char *tmp = _str; if (((*(int *)(_str - 4))-1) != 0) { (*(int *)(_str - 4))--; _str = new char[strlen(_str) + 5]; (*(int *)(_str + 4)) = 1; _str = _str - 4; strcpy(_str, tmp); } return _str[index]; } private: char *_str; };
但是这样做也有一个坏处。就是指向同一块空间的指针,只要改一个指针指向的内容,等于其他的指针指向的内容也跟着改变了。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
分享文章:C++String的实现-创新互联
网页地址:http://scyanting.com/article/dijddi.html