发布时间:2025-06-24 19:00:28  作者:北方职教升学中心  阅读量:508


注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大 小,如果是将元素个数减少,底层空间总大小不变。

  • 5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(UTF-8)的序列,这个
  • 类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。s2共用同一块内存空间,在释放时同一块 空间被释放多次而引起程序崩溃,这种拷贝方式,称为浅拷贝。
  • 3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>
  • string;
  • 4. 不能操作多字节或者变长字符的序列。
  • 故总共占16+4+4+4=28个字节。一般情 况都是按照深拷贝方式提供

    3.4 写时拷贝

    写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。
    https://coolshell.cn/articles/12199.html
    https://coolshell.cn/articles/1443.html

    3.5 string类的模拟实现

    //string.h#pragma once#include<iostream>#include<assert.h>using namespace std;namespace mystr {	class string	{	public:		//迭代器, 因为字符串底层内存连续, 所以可以简单的定义成指针		typedef char* iterator;		typedef const char* const_iterator;		//配合范围for循环		iterator begin() { return _str; }		iterator end() { return _str + _size; }		//兼容常量字符串		const_iterator begin() const { return _str; }		const_iterator end() const { return _str + _size; }		//string();		string(const char* str = "");		string(const string& s);		string& operator=(string temp) { swap(temp); return *this; }		~string() { delete[] _str; _str = nullptr; _size = _capacity = 0; }		//返回C语言字符数组		const char* c_str() const { return _str; }		size_t size() const { return _size; }		char& operator[](size_t pos) { assert(pos < _size); return _str[pos]; }		const char& operator[](size_t pos) const{ assert(pos < _size); return _str[pos]; }		//重置大小		void reserve(size_t n);		void push_back(char ch) { insert(_size, ch); }		void append(const char* str) { insert(_size, str); }		string& operator+=(char ch) { insert(_size, ch); return *this; }		string& operator+=(const char* str) { insert(_size, str); return *this; };		void insert(size_t pos, char ch);		void insert(size_t pos, const char* str);		void erase(size_t pos = 0, size_t len = npos);		size_t find(char ch, size_t pos = 0) {			for (size_t i = pos; i < _size; i++) if (_str[i] == ch) return i;			return npos;		}		size_t find(const char* str, size_t pos = 0) { return strstr(_str + pos, str) - _str; }		void swap(string& s);		string substr(size_t pos = 0, size_t len = npos);		bool operator<(const string& s) const { return strcmp(_str, s._str) < 0; }		bool operator>(const string& s) const { return !(*this <= s); }		bool operator<=(const string& s) const { return !(*this > s); }		bool operator>=(const string& s) const { return !(*this < s); }		bool operator==(const string& s) const {return strcmp(_str, s._str) == 0;}		bool operator!=(const string& s) const { return !(*this == s); }		void clear() { _str[0] = '\0'; _size = 0; }	private:		char* _str;		size_t _size;		size_t _capacity;		//一般static变量的定义要放在类外, 整型是特例		const static size_t npos = -1;	};	void swap(string& s1, string& s2);	istream& operator>>(istream& ci, string& s);	ostream& operator<<(ostream& co, string& s);}
    //string.cpp#include "string.h"namespace mystr {	string::string(const char* str):_size(strlen(str)) {		_str = new char[_size + 1];		_capacity = _size;		strcpy(_str, str);	}	string::string(const string& s) {		string temp(s._str);		swap(temp);	}	void string::reserve(size_t n) {		if (_capacity < n) {			char* temp = new char[n + 1];			strcpy(temp, _str);			delete[] _str;			_str = temp;			_capacity = n;		}	}	void string::insert(size_t pos, char ch) {		assert(pos <= _size);		if (_size == _capacity) {			size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;			reserve(newcapacity);		}		size_t end = _size + 1;		while (end > pos) _str[end] = _str[end - 1], --end;		_str[pos] = ch;		_size++;	}	void string::insert(size_t pos, const char* str) {		assert(pos <= _size);		size_t len = strlen(str);		if (_size + len > _capacity) reserve(_size + len);		size_t end = _size + len;		while (end > pos + len - 1) _str[end] = _str[end - len], --end;		memcpy(_str + pos, str, len);		_size += len;	}	void string::erase(size_t pos, size_t len) {		if (len > _size - pos) _str[pos] = '\0', _size = pos;		else strcpy(_str + pos, _str + pos + len), _size -= len;	}	void string::swap(string& s) {		char* temp = _str;		_str = s._str;		s._str = temp;		std::swap(_size, s._size);	}	string string::substr(size_t pos, size_t len) {		if (len > _size - pos) { string sub(_str + pos); return sub; }		else {			string sub;			sub.reserve(len);			for (size_t i = pos; i < pos + len; i++) sub += _str[i];			return sub;		}	}	void swap(string& s1, string& s2){ s1.swap(s2); }	istream& operator>>(istream& ci, string& s) {		s.clear();		char ch = ci.get();		while (ch != ' ' && ch != '\n') s += ch, ch = ci.get();		return ci;	}	ostream& operator<<(ostream& co, string& s) {		for (size_t i = 0; i < s.size(); i++) co << s[i];		return co;	}}
    //test.cpp#include "string.h"namespace mystr {	void test1() {		string s1 = "1111";		string s2 = s1;		cout << s1.c_str() << endl << s2.c_str() << endl;		cout << s1.size() << endl;	}	void test2() {		string s1 = "111";		string s2 = "222222";		s1 = s2;		cout << s1.c_str() << endl;	}	void test3() {		string s1 = "111222333";		for (auto& i : s1) i += 3;		cout << s1.c_str() << endl;		const string s2 = "111222333";		for (auto& i : s2) cout << i;		cout << endl;		for (size_t i = 0; i < s1.size(); i++) cout << (s1[i] += 2);		cout << endl;	}	void test4() {		string s1 = "sadfsf";		s1.insert(2, '-');		cout << s1.c_str() << endl;		s1.insert(0, '-');		cout << s1.c_str() << endl;		s1.insert(2, "11111");		cout << s1.c_str() << endl;		s1.insert(0, "222222");		cout << s1.c_str() << endl;	}	void test5() {		string s1 = "asgfidsgf";		s1.push_back('-');		cout << s1.c_str() << endl;		s1.append("=====");		cout << s1.c_str() << endl;		s1 += 'w';		cout << s1.c_str() << endl;		s1 += "0000";		cout << s1.c_str() << endl;		s1.erase(10);		cout << s1.c_str() << endl;		s1.erase(7, 100);		cout << s1.c_str() << endl;		s1.erase(3, 2);		cout << s1.c_str() << endl;		s1.erase(0);		cout << s1.c_str() << endl;	}	void test6() {		string s1 = "ksjfghks";		cout << s1.find('h', 2) << endl;		cout << s1.find("ghk", 2) << endl;		cout << s1.find("ghksgs", 2) << endl;	}	void test7(){		string s1 = "sggsdsdf";		string s2 = "sdgfrgdb";		cout << s1.c_str() << endl;		cout << s2.c_str() << endl;		swap(s1, s2);		cout << s1.c_str() << endl;		cout << s2.c_str() << endl;		s1.swap(s2);		cout << s1.c_str() << endl;		cout << s2.c_str() << endl;		string s3 = s1.substr(2, 5);		cout << s3.c_str() << endl;	}	void test8() {		string s1, s2;		cin >> s1 >> s2;		cout << s1 << endl << s2 << endl;	}}int main() {	mystr::test8();	return 0;}