赞
踩
浅拷贝:类的所有对象的成员变量指针指向同一块空间(成员变量是开辟在堆区的),类默认的拷贝构造函数和赋值运算符重载都采用浅拷贝,如果不加以处理,当析构函数对空间进行释放时,就会出现堆区空间二次释放的问题。但是浅拷贝也可以起到节省内存空间的作用,这里就需要利用静态的成员变量来进行对象计数,析构函数中 对计数进行判断,如果只剩下一个对象再进行真正的析构操作。
深拷贝:对于拷贝构造和赋值运算符重载重新实现,赋值时每次都要开辟新空间。注意赋值运算符重载中,需要进行旧空间释放(不然会造成内存泄漏)和是否是自身赋值的判断。
所有对象都只是访问数据而不修改,浅拷贝是可以的,但是当有对象要进行数据修改时就应该按深拷贝来实现。深拷贝和浅拷贝(对象计数)的实现:这种所有的对象都进行统一引用计数的方式是错误的,比如s3应当和s1、s2没有关联,而且这里的成员变量一改俱改。
- #define _CRT_SECURE_NO_WARNINGS
- #include<iostream>
- #include<vld.h>
- using namespace std;
-
- class String
- {
- friend ostream& operator<<(ostream& cout, const String& s);
-
-
- public:
- String(const char* str="")
- {
- this->m_data = new char[strlen(str) + 1];
- strcpy(m_data, str);
- this->m_count++;
- }
-
- String(const String& s)
- {
- /* this->m_data = new char[strlen(s.m_data)+1];
- strcpy(this->m_data, s.m_data);*/
- this->m_data = s.m_data;
- this->m_count++;
- }
-
- String& operator=(const String& s)
- {
- if (this != &s)
- {
- this->m_data = s.m_data;
- /*delete this->m_data;
- this->m_data = new char[strlen(s.m_data) + 1];
- strcpy(this->m_data, s.m_data);*/
- this->m_count++;
- }
- return *this;
- }
-
- ~String()
- {
- if (--this->m_count == 0)//浅拷贝和浅赋值
- {
- delete[] m_data;
- m_data = nullptr;
- }
- }
-
- public:
-
- void do_uper(char* p)
- {
- while (*p != '\0')
- {
- if (*p >= 'a' && *p <= 'z')
- {
- *p -= 32;
- }
- p++;
- }
- }
-
- void to_upper()//写时拷贝,只有在修改对象成员变量时才开辟新空间
- {
- char* p=NULL;
-
- if (this->m_count > 1)
- {
- char* tmp = new char [strlen(m_data) + 1];
- strcpy(tmp, this->m_data);
- this->m_data = tmp;
- p = tmp;
- this->m_count--;
- }
-
- else
- {
- p = this->m_data;
- }
-
- do_uper(p);
- }
-
- private:
- char* m_data;
- static int m_count;
- };
- int String::m_count = 0;
-
- ostream& operator<<(ostream& cout, const String& s)
- {
- cout << s.m_data << endl;
- return cout;
- }
-
- void test01()
- {
- String s("abc");
- }
-
- void test02()
- {
- String s1("abc");
- String s2 = s1;
- String s3;
- s3 = s1;
- cout << s1;
- cout << s2;
- cout << s3;
- }
-
- void test03()
- {
- String s1("abc");
- String s2 = s1;
- String s3("xyz");
- s1.to_upper();
- cout << s1;
- cout << s2;
- }
-
- int main()
- {
- //test01();
- test03();
-
- system("pause");
- return 0;
- }
String类的写时拷贝:
- #define _CRT_SECURE_NO_WARNINGS
- #include<iostream>
- #include<assert.h>
- #include<vld.h>
- using namespace std;
-
- //#define DISPLAY
-
- class String_rep
- {
- friend class String;
- public:
- String_rep(const char* str = "") :m_count(0)
- {
- #ifdef DISPLAY
- cout << "Creat String_Rep Obj" << endl;
- #endif
- this->m_data = new char[strlen(str) + 1];
- strcpy(m_data, str);
- }
-
- String_rep(const String_rep& rep)
- {
- this->m_data = rep.m_data;//浅拷贝
- //increament();
- }
-
- String_rep& operator=(const String_rep& rep)
- {
- if (this != &rep)
- {
- this->m_data = rep.m_data;
- //increament();
- }
- return *this;
- }
-
- char* getData()
- {
- return m_data;
- }
-
- ~String_rep()
- {
- #ifdef DISPLAY
- cout << "Free String_Rep Obj" << endl;
- #endif
- delete[] this->m_data;
- this->m_data = NULL;
- }
-
- void increament()
- {
- this->m_count++;
- }
-
- void decreament()
- {
- if (--m_count == 0)
- {
- delete this;//自杀式释放
- }
- }
-
- private:
- char* m_data;
- int m_count;
- };
-
- class String
- {
- friend ostream& operator<<(ostream& cout, const String& s);
-
- public:
- String(const char* str = "") :pn(new String_rep(str))
- {
- #ifdef DISPLAY
- cout << "Creat String Obj" << endl;
- #endif
- pn->increament();
- }
- String(const String& s):pn(s.pn)
- {
- pn->increament();
- }
- String& operator=(const String& s)
- {
- if (this != &s)
- {
- pn->decreament();
- pn = s.pn;
- pn->increament();
- }
- return *this;
- }
-
- void to_upper()
- {
- String_rep* new_pn = new String_rep(pn->m_data);
- pn->decreament();
- pn = new_pn;
- pn->increament();
-
- char* p = pn->m_data;
- while (*p != '\0')
- {
- if (*p >= 'a' && *p <= 'z')
- *p -= 32;
- p++;
- }
- }
-
- ~String()
- {
- #ifdef DISPLAY
- cout << "Free String Obj" << endl;
- #endif
- pn->decreament();
- }
- private:
- String_rep* pn;
- };
-
- ostream& operator<<(ostream& cout, const String& s)
- {
- cout << s.pn->getData() << endl;
- return cout;
- }
-
- void test01()
- {
- String s1("abc");
- //{
- // String s1 = s;
- //}
-
- String s2 = s1;
- String s3("xyz");
- }
-
- void test02()
- {
- String s("abc");
- String s1("xyz");
- String s2 = s1;
- s = s1;
- }
-
- void test03()
- {
- String s1("abc");
- String s2 = s1;
- String s3 = s2;
- cout <<"s1="<< s1;
- cout <<"s2="<<s2;
-
- s1.to_upper();
- cout <<"s1="<< s1;
- cout <<"s2="<< s2;
- }
-
-
- int main()
- {
- //test01();
- test03();
- system("pause");
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。