• 对象的深拷贝和浅拷贝


    在copy一个对象时(用一个对象去初始化另外一个对象),会调用类中的拷贝构造函数。如果我们自己没有在类里面写拷贝构造函数,则C++编译器会调用默认的拷贝构造函数。

    浅拷贝:如果类定义的对象包含的某个成员是动态内存分配产生的(指针变量成员),你先用该类定义了一个对象1,然后又用这个对象1去初始化另外一个对象2。如果在类里面,没有自己写拷贝构造函数,C++编译器会调用默认的拷贝构造函数,只能将对象1的成员的值赋给对象2的成员,对象1成员指向的内存并没有被复制,也就是说对象1指针成员和对象2指针成员指向的是同一块内存。这样在析构对象时,先析构对象2,对象2指针成员指向的内存被free。由于对象1指针成员和对象2指针成员的值一样,指向的是同一块内存,析构对象1的指针成员时,它所指向的那块内存之前已经被对象2的指针成员free,没法再次free,就会出现宕机(down机),这就是浅拷贝问题。浅拷贝问题在编译阶段不会出问题,只有当程序运行的时候才会发现问题。

                                                         

                                                                                浅拷贝问题图解

    如果要解决浅拷贝问题,那就必须深拷贝。所谓的深拷贝,就是说不仅将对象1的值拷贝给对象2,而且要将对象1指针成员指向的内存空间也要赋值一份给对象2。这时候,我们就不能再用C++编译器给我们提供的默认拷贝构造函数,必须自己写一份拷贝构造函数。

    关于浅拷贝和深拷贝问题,可以参考以下代码:

     1 //myname.h
     2 #pragma once
     3 class myname
     4 {
     5 public:
     6     myname(const char*);
     7     myname(const myname&);
     8     ~myname(void);
     9     void printN();
    10 
    11 private:
    12     int len;
    13     char* p;
    14 };
    15 
    16 
    17 //myname.cpp
    18 #include "myname.h"
    19 #include "string.h"
    20 #include "malloc.h"
    21 #include <iostream>
    22 
    23 #define _CRT_SECURE_NO_WARNINGS
    24 
    25 //构造函数
    26 myname::myname(const char* myp)
    27 {
    28     len=strlen(myp);
    29     p=(char*)malloc(sizeof(char)*(len+1));
    30     strcpy(p,myp);
    31 }
    32 
    33 //拷贝构造函数。如果不自己写该函数,C++编译器会调用默认的拷贝构造函数,则会发生浅拷贝。自己写了该函数,C++编译器就会调用该函数,发生的是深拷贝
    34 myname::myname(const myname& n)
    35 {
    36     len=n.len;
    37     p=(char*)malloc(sizeof(char)*(len+1));
    38     strcpy(p,n.p);
    39 }
    40 
    41 
    42 void myname::printN()
    43 {
    44     std::cout<<"name:"<<p<<std::endl;
    45 }
    46 
    47 
    48 myname::~myname(void)
    49 {
    50     free(p);
    51     p=NULL;
    52     len=0;
    53 }
    54 
    55 
    56 //main函数
    57 #include<iostream>
    58 #include "myname.h"
    59 
    60 using namespace std;
    61 
    62 int main()
    63 {
    64     
    65     myname name1("Zhang wuji");
    66     myname name2(name1);
    67     name2.printN();
    68     
    69 
    70     return 0;
    71 }
  • 相关阅读:
    HDU5597/BestCoder Round #66 (div.2) GTW likes function 打表欧拉函数
    HDU5596/BestCoder Round #66 (div.2) 二分BIT/贪心
    HDU 5596/BestCoder Round #66 (div.2) GTW likes math 签到
    BZOJ 1877: [SDOI2009]晨跑 费用流
    BZOJ 1452: [JSOI2009]Count 二维树状数组
    BZOJ 1143 1143: [CTSC2008]祭祀river 最长反链
    Codeforces Round #335 (Div. 2) D. Lazy Student 贪心
    Codeforces Round #335 (Div. 2) C. Sorting Railway Cars 连续LIS
    Codeforces Round #335 (Div. 2) A. Magic Spheres 模拟
    UVALive 6187 Never Wait for Weights 带权并查集
  • 原文地址:https://www.cnblogs.com/jswu-ustc/p/8334954.html
Copyright © 2020-2023  润新知