2.由深拷贝和浅拷贝引发的写时拷贝技术
一、相关问题
我们知道,浅拷贝会引发重复释放,导致程序崩溃。而深拷贝虽不会出现上述问题,但是内存空间开销大。所以,有没有一种方法,
既节省空间,又不会造成程序崩溃呢?
二、写时拷贝技术
写时拷贝(Copy-on-write):如果有多个呼叫者同时要求相同资源,他们会共同取得相同的指标指向相同的资源,直到某个呼叫者
尝试修改时,才会复制一个副本给该呼叫者。
三、例子
实现string类,在string中添加引用计数器类成员
class String; //引用计数器类 class String_rep { friend class String; friend ostream& operator<<(ostream& out, String const& s); public: String_rep(const char* str = "") : m_UseCount(0){ if(NULL == str){ m_data = new char[1]; m_data[0] = '\0'; }else{ m_data = new char[strlen(str) + 1]; strcpy_s(m_data, strlen(str) + 1, str); } } String_rep(String_rep const& that){ m_data = new char[strlen(that.m_data) + 1]; strcpy_s(m_data, strlen(that.m_data) + 1, that.m_data); } String_rep& operator=(String_rep const& rhs){ if(this != &rhs){ delete[] m_data; m_data = new char[strlen(rhs.m_data) + 1]; strcpy_s(m_data, strlen(rhs.m_data) + 1, rhs.m_data); } return *this; } ~String_rep(){ delete[] m_data; m_data = NULL; } public: void Increment(){ ++m_UseCount; } void Decrement(){ if(--m_UseCount == 0){ delete this; } } private: char* m_data; int m_UseCount; }; class String { friend ostream& operator<<(ostream& out, String const& s){ return out << s.m_rep->m_data; } public: String(const char* str = ""){ m_rep = new String_rep(str); m_rep->Increment(); } String(const String& that){ m_rep = that.m_rep; m_rep->Increment(); } String& operator=(String const& rhs){ if (this != &rhs){ m_rep->Decrement(); m_rep = rhs.m_rep; m_rep->Increment(); } return *this; } ~String(){ m_rep->Decrement(); } public: void ToUpper(){ if (m_rep->m_UseCount > 1){ String_rep* newRep = new String_rep(m_rep->m_data); m_rep->Decrement(); m_rep = newRep; m_rep->Increment(); } char* ch = m_rep->m_data; while (*ch != '\0'){ *ch -= 32; ++ch; } } private: String_rep* m_rep; }; int main() { String s1("hello"); String s2 = s1; String s3("world"); s3 = s2; cout << "s1 = " << s1 << endl; cout << "s2 = " << s2 << endl; cout << "s3 = " << s3 << endl; cout << "----------------------------" << endl; s2.ToUpper(); cout << "s1 = " << s1 << endl; cout << "s2 = " << s2 << endl; cout << "s3 = " << s3 << endl; system("pause"); return 0; }
运行结果:
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步