C++中的默认函数 深拷贝与浅拷贝 深赋值与浅赋值

1、C++中什么都不写,就有6个默认函数,由系统自动提供:

构造函数,拷贝构造函数,赋值语句,析构函数,对一般对象的取地址符,对常对象的取地址重载;

对&运算符的重载:

Test t3;

Test *pt = &t3;

Test* operator&(){
    return this;
}

对常对象的取地址重载;

const Test t4;

const Test *pt1 = &t4;

const Test* operator&()const{
    return this;
}

2、深拷贝与浅拷贝

#include<iostream>
#include<string.h>
#include<malloc.h>
using namespace std;

class String{
public:
    String(const char *str = ""){
        if(str == NULL){
            data = new char;
            data[0] = 0;
        }else{
            data = new char[strlen(str) + 1];
            strcpy(data, str);
        }
    }
    ~String(){
        delete []data;
    }
private:
    char *data;
};

int main(void){
    String t1("abcdef");
    String t2 = t1;
    String t3("hello");
    t3 = t1;

    return 0;
}

运行结构如下:

可以知道,程序崩了,我们用的是系统默认的拷贝构造函数和赋值语句,此时只是各成员之间的赋值,

        两个对象通过默认的拷贝构造,成员data之间相互赋值,使得data不同,data的值相同,指向了同一空间;

        此时在最后调用析构函数时,形成了对同一空间的多次释放,是错误操作!!!,这就是浅拷贝。

        两个对象通过默认的赋值语句,成员data之间相互赋值,使得data不同,data的值相同,指向了同一空间,浅赋值。

解决方案,此时应给自己写拷贝构造和赋值语句,达成深拷贝:

    String(const String &s){
        data = new char[strlen(s.data) + 1];
        strcpy(data, s.data);
    }
    String& operator=(const String &s){
        if(this != &s){
            delete []data;
            data = new char[strlen(s.data) + 1];
            strcpy(data, s.data);
        }

        return *this;
    }

深拷贝和深赋值的意思:就是重新申请空间,各自保存自己的,最后在自己释放自己的,保证了对内存访问的安全性;

深赋值应当注意以下四步:

(1)、判断自己是否给自己赋值

(2)、释放原有空间      //有可能在构造对象时,已经指向了某一空间,此时就得先释放,不然就内存泄漏

(3)、申请空间进行赋值

(4)、返回引用空间

时间: 2024-10-10 20:11:13

C++中的默认函数 深拷贝与浅拷贝 深赋值与浅赋值的相关文章

C++中的默认函数与default和delete用法

时间:2014.05.08 地点:基地 -------------------------------------------------------------------------------- 一.类中的默认函数 a.类中默认的成员函数 1.默认构造函数 2.默认析构函数 3.拷贝构造函数 4.拷贝赋值函数 5.移动构造函数 6.移动拷贝函数 b.类中自定义的操作符函数 1.operator 2.operator& 3.operator&& 4.operator* 5.op

JavaScript中面向对象的的深拷贝和浅拷贝

理解深拷贝和浅拷贝之前需要弄懂一些基础概念,内存中存储的变量类型分为值类型和引用类型. 1.值类型赋值的存储特点, 将变量内的数据全部拷贝一份, 存储给新的变量. 例如:var num = 123 :var num1=num; 表示变量中存储的数字是 123.然后将数据拷贝一份,就是将 123 拷贝一份. 那么内存中有 2 个 数组;将拷贝数据赋值给 num2,其特点是在内存中有两个数据副本.这可以理解为浅拷贝. 2.引用类型的赋值. var o={name:'张三‘}: var obj=o;

Java中的深复制和浅赋值

深复制和浅复制也称为深拷贝和浅拷贝.简单的说就是创建一个和当前对象一模一样的对象.在日常编码的过程中使用的几率并不多,但在面试中却会被经常问到. 了解深复制和浅复制的原理后,可以帮助我们对Java中的值传递和引用传递有更深刻的理解. 浅复制 下面的实例中,我们创建一个原始类Monster,调用对象的clone方法复制一个新的对象. 注意:要调用对象的clone方法,需要让类实现Cloneable接口,并重写clone方法 public class Monster implements Clone

c++中 拷贝构造函数的深拷贝和浅拷贝--“浅拷贝”与“深拷贝”

C++中对象的复制就如同"克隆",用一个已有的对象快速地复制出多个完全相同的对象.一般而言,以下三种情况都会使用到对象的复制: (1)建立一个新对象,并用另一个同类的已有对象对新对象进行初始化,例如: class Rect { private: int width; int height; }; Rect rect1; Rect rect2(rect1); // 使用rect1初始化rect2,此时会进行对象的复制 (2)当函数的参数为类的对象时,这时调用此函数时使用的是值传递,也会产

Javascript中的深拷贝和浅拷贝

文章目录 JavaScript中的变量类型 深拷贝和浅拷贝的理解 深拷贝和浅拷贝的实现方式 为什么需要深拷贝和浅拷贝 JavaScript中的变量类型 (1).基本类型 JavaScript中的基本类型有五种: null.undefined.boolean.string.number. 变量是按值存放的,存放在栈中的简单数据段,可以直接访问. (2).引用类型 引用类型包括对象和数组,其存储在堆当中,而变量是指针,指向堆. 当我们访问的时候,实际上是访问指针,然后指针去寻找对象或数组. 深拷贝与

Python 深拷贝和浅拷贝

Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 对象赋值 直接看一段代码: will=["Will",28,["Python","C#","JavaScript"]] wilber=will print id(will) print will print [id(x) for x in will] print id

图解Python深拷贝和浅拷贝

Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 对象赋值 直接看一段代码: will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = will print id(will) print will print [id(ele) for ele in wi

【转载】图解 Python 深拷贝和浅拷贝

作者:田小计划 出处:http://www.cnblogs.com/wilber2013/ Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 对象赋值 直接看一段代码: will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = will print id

从JS的深拷贝与浅拷贝到jq的$.extend()方法

一.堆内存与栈内存 堆和栈都是内存中划分出来的用来存储的区域,栈为自动分配的内存空间,它由系统自动释放,堆为动态分配的内存,大小不定也不会自动释放. 二.js基本数据类型与引用类型的不同 基本数据类型(boolean,undefined,null,string,number) 1.基本数据类型存放在栈内存中 是存放在栈中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问. 2.基本数据类型值不可变 js中给基本类型赋值或操作基本类型数据时,并没有改变基本类型的原