企业网站建设公司司,云南省建设厅网站二级建造师,公司简介概况怎么写,重庆网站建设微信开发目录
浅拷贝
深拷贝
赋值运算符重载的深拷贝 在学习C类和对象时我们学习了浅拷贝#xff0c;本期我们将再次回顾浅拷贝并为大家讲述深拷贝的概念。
浅拷贝 在学习类和对象时我们学习了拷贝构造函数的概念#xff0c;而且我们也知道#xff0c;因为拷贝构造函数属于类的默…目录
浅拷贝
深拷贝
赋值运算符重载的深拷贝 在学习C类和对象时我们学习了浅拷贝本期我们将再次回顾浅拷贝并为大家讲述深拷贝的概念。
浅拷贝 在学习类和对象时我们学习了拷贝构造函数的概念而且我们也知道因为拷贝构造函数属于类的默认成员函数吗所以当我们没有显示定义拷贝构造函数时编译器会生成拷贝构造函数编译器生成的拷贝构造函数对内置类型成员变量会完成字节序的值拷贝对于自定义类型会去调用其拷贝构造函数。这里对内置类型成员变量进行的字节序值拷贝我们就称作浅拷贝为什么我们我们要称字节序的值拷贝为浅拷贝呢 我们通过依然自定义的string类中的拷贝构造函数为大家讲解
代码如下
class string{public:string(const char* str):_str(new char[strlen(str) 1]){strcpy(_str, str);}~string(){delete [] _str;_str nullptr;}private:char* _str;};void test1(){string s1(hello yjd);//调用拷贝构造函数string s2(s1);//调用赋值运算符重载string s3(hello world);s3 s1;} 如上代码我们自己定义了一个string类string类由于我们没有声明拷贝构造函数所以编译器会生成默认的拷贝构造函数但是生成的默认的拷贝构造函数会对内置类型进行值拷贝就会将s1对象的_str成员变量的值传给s2对象的_str成员变量。 所以就会导致下面这种情况图示如下 运行截图如下: 不难发现编译器提示我们出现了错误这是因为编译器默认生成的拷贝构造函数对于内置类型是值拷贝所以s1._str的值会赋给s2._str就会导致两个指针变量指向了统一块动态申请的空间既然是动态申请的空间在最后为了防止内存泄漏肯定是要使释放的因为两个对象在小销毁之前都会调用析构函数进行资源的清理所以这就会导致统一块空间被释放了两次这边会导致错误所以为了防止这种情况的出现在此情境下诞生了深拷贝。 深拷贝 什么是深拷贝说白了深拷贝就是为了解决在堆上申请的空间被释放两次的问题针对上述浅拷贝所产生的现象为了防止两个指针指向了同一块空间我们可以先让s2在堆上申请与s1大小相同的空间在C语言中我们学习了字符串函数strcpy我们可以通过这个函数实现两个字符串值的传递。 图示如下 通过图示不难发现两个对象的成员变量指向了两个不同的空间所以此时我们也就不用担心在堆区开辟的空间被释放两次的问题所以深拷贝就解决了浅拷贝中所带来的不足。 代码如下 string(string s):_str(new char[strlen(s._str)1]){strcpy(_str, s._str);} 上述代码便是我们自己生成的拷贝构造函数代码所以在今后学的的数据结构只要需要在堆上动态开辟空间我们就需要自己定义拷贝构造函数。 赋值运算符重载的深拷贝 在学习类和对象时我们也学习了赋值运算符重载赋值运算符重载和拷贝构造函数的区别是 1.拷贝构造函数是用一个已经存在的对象初始化一个刚刚创建的对象。 2.赋值运算符重载是两个已经存在的对象之间进行赋值。 图示如下 解析因为赋值运算符重载也属于类的成员函数当我们没有显示定义赋值运算符重载时编译器也会默认生成一个赋值运算符重载但是默认生成的赋值运算符重载和默认生成的拷贝构造函数是类似的对于内置类型的成员变量会完成字节序的值拷贝浅拷贝通过默认拷贝构造函数我们知道浅拷贝是存在弊端的所以对于在堆上开辟空间的数据结构我们必须自己显示定义赋值运算符重载。 其实整个过程和拷贝构造函数类似不过赋值运算符重载我们要先释放掉原来的空间释放掉原来的空间之后在动态开辟一块与s1大小相同的空间然后将这块空间的地址传给s3._str,然后通过strcpy函数实现字符串值的拷贝。 代码如下
string operator(string s){if (this ! s){char* tmp new char[strlen(s._str) 1];strcpy(tmp, s._str);delete[]_str;_str tmp;}return *this;}
截图如下 注意代码中我们有两个需要注意的地方 1.自己不需要给自己赋值所以直接返回自身即可。 2.为了避免申请空间失败仍然释放掉原来空间的这种情况我们定义了一个中间变量tmp当空间申请失败时我们则不释放原来的空间当空间申请成功时我们先赋值给临时字符串tmp最后再将临时字符串赋值给成员变量_str就可以完成赋值运算符重载。 好了,深拷贝和浅拷贝的内容到这里就全部结束了我们本次为大家带来的是传统版本的深拷贝后期会为大家讲述效率更高的的深拷贝的方法。
本期内容到此结束^_^