了解过C++语言的人,都应该知道,C++语言中的构造函数,析构函数,拷贝构造函数,赋值运算符重载函数,如果不定义,编译器会自动生成的,当然,生成的只是一些最基本的,在达不到我们要求的条件下,就需要我们自己重新定义这些函数。
十载的余江网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都营销网站建设的优势是能够根据用户设备显示端的尺寸不同,自动调整余江建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联公司从事“余江网站设计”,“余江网站推广”以来,每个客户项目都认真落实执行。我们现在说的讲的是深拷贝与浅拷贝,当然讨论这个问题的基础,一般情况下是我们定义的变量是以指针形式出现的,原因就在于,不论赋值还是拷贝,我们要实现两个指针指向的内容一致,那我得到新的指针和原指针是指向同一块内存空间还是两块内存空间的相同内容。如果是指向同一块空间,就存在了安全隐患,我们在自己管理空间时,就很有可能对一块空间进行了多次的释放,有些编译器下会报错,甚至直接奔溃,有些编译器虽不会抛出异常,但也会对后续的程序造成未知的错误。
那么,现在就以String为例,看看如何解决这些问题。
//参数列表中,pstr为char* 类型,s为String类型
//实现方法1:
class String { friend ostream& operator<<(ostream& _out, const String& s); public: String(const char* pstr) :_str(new char[strlen(pstr)+1]) { strcpy(_str,pstr); cout << "构造" << endl;//做标识 } String(const String& s) :_str(new char[strlen(s._str) + 1]) { strcpy(_str,s._str); cout << "拷贝构造"<//*****************************************************************************************
//String类的实现2
class String { friend ostream& operator<<(ostream& _out, const String& s); public: String(const char* str) :_str(new char[strlen(str)+1])//同上 { strcpy(_str,str); } //拷贝构造 String(const String& s) : _str(NULL) { String tmp(s._str); std::swap(_str,tmp._str); } //赋值运算符重载 //String&operator=(const String& s) //{ // if (this != &s) // { // char* tmp(s._str);//用s._str或者s实例化tmp都可以 // std::swap(_str,tmp); // } // return *this; //} //赋值运算符重载之开辟空间法 String&operator=(const String& s) { if (this != &s) { char* tmp = new char[strlen(s._str) + 1]; strcpy(tmp,s._str); delete[]_str; _str = tmp; } return *this; } //析构 ~String() { if (NULL == _str) { delete[] _str; _str = NULL; } } private: char* _str; }; //输出运算符重载 ostream& operator<<(ostream& _out,const String& s) { _out << s._str<< endl; return _out; }// String类的实现3------>浅拷贝实现防止内存的多次释放
class String { friend ostream& operator<<(ostream& _out, const String& s); public: String(const char* pdata) :_str(new char[strlen(pdata)+1]) , _count(new int) { strcpy(_str,pdata); *_count = 1; } String(const String& s) :_str(s._str) , _count(s._count) { _count++; } String& operator=(const String& s) { if (this != &s) { if (--(*_count) == 0) { delete[]_str; delete _count; } _count = s._count; _str = s._str; _count++; } return* this; } ~String() { if (--(*_count) == 0) { delete[] _str; delete _count; } } private: char* _str; int* _count; }; //输出运算符重载 ostream& operator<<(ostream& _out,const String& s) { _out << s._str<< endl; return _out; }//*****************************************************************************************
友元函数受第一参数的限制,只能采用类外定义,引入友元
方法三,关于引入计数器,在面试过程中,这是最不推荐的方法,HR往往更倾向于让你写出深拷贝的方法。
深拷贝与浅拷贝是面试过程中经常出现的题目,弄清楚这类问题是非常必要的
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。
文章标题:从String类中看C++当中的深拷贝与浅拷贝解-创新互联
文章路径:http://cdkjz.cn/article/dsjoeh.html