zoukankan      html  css  js  c++  java
  • [C++] 深拷贝和浅拷贝

    c++的类中含有指针类型时,在进行拷贝时要注意深拷贝和浅拷贝的问题。

    (1) 浅拷贝采用"位拷贝"的方式。对于基础类型,如int, float等,可以直接copy过来;

    但是对于指针类型,在copy时要格外注意,浅拷贝只copy了指针指向的地址,并未复制创建该地址上的对象内容,容易引发内存泄露、多次析构等问题。

    (2) 深拷贝则为新对象的成员重新开辟内存空间,每个对象共同拥有自己的资源,必须显式提供拷贝构造函数和赋值运算符。

    1. 浅拷贝的问题

    以类File为例,首先创建了File类型的一个对象a, File类型的对象b是由a 浅拷贝得到。

    在浅拷贝时,对于a中的指针类型对象_fp,b只copy了a中_fp指针指向的对象的地址

    那么浅拷贝后,a, b对象的_fp指针都指向了同一块内存

    这在类进行析构时很容易出现被多次析构的问题。 

    #include <iostream>
    using namespace std;
    
    class File
    {
    public:
        explicit File(const char *file_name) {};
        ~File() {};
    
        void addr_fp() {
            cout << _fp << endl;
        }
    
    private:
        FILE *_fp; 
    };
    
    int main()
    {
        File a("./a.txt");
        cout << "a._fp addr" << endl;
        a.addr_fp();
    
        File b = a;
        cout << "b._fp addr" << endl;
        b.addr_fp();
    
        return 0;
    }
    
    /** output
    
    a._fp addr
    0x7ffee45649d8
    b._fp addr
    0x7ffee45649d8
    
    **/

    2. 解决方法

    对于含有指针类型的类,可以采用进制拷贝构造、赋值构造等方式来避免(1)中的问题。(RAII没有复制行为)

    下例中通过定义一个拷贝和赋值构造的宏,并在private中进行声明,

    那么如果有企图对该类对象进行拷贝或赋值构造,会触发private 的constructor引发报错。

    #include <iostream>
    using namespace std;
    
    #define DISALLOW_COPY_AND_ASSIGN(TypeName) 
            TypeName(const TypeName&);
            TypeName& operator=(const TypeName&) 
    
    
    class File
    {
    public:
        explicit File(const char *file_name) {};
        ~File() {};
    
        void addr_fp() {
            cout << _fp << endl;
        }
    
    private:
        FILE *_fp; 
        DISALLOW_COPY_AND_ASSIGN(File);
    };
    
    int main()
    {
        File a("./a.txt");
        cout << "a._fp addr" << endl;
        a.addr_fp();
    
        File b = a;
        cout << "b._fp addr" << endl;
        b.addr_fp();
    
        return 0;
    }
    
    
    /** output
    
    deep_shallow_copy.cpp:30:11: error: calling a private constructor of class 'File'
            File b = a;
                     ^
    deep_shallow_copy.cpp:21:27: note: declared private here
            DISALLOW_COPY_AND_ASSIGN(File);
                                     ^
    1 error generated.
    
    **/

  • 相关阅读:
    Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    用户画像——“打标签”
    python replace函数替换无效问题
    python向mysql插入数据一直报TypeError: must be real number,not str
    《亿级用户下的新浪微博平台架构》读后感
    【2-10】标准 2 维表问题
    【2-8】集合划分问题(给定要分成几个集合)
    【2-7】集合划分问题
    【2-6】排列的字典序问题
    【2-5】有重复元素的排列问题
  • 原文地址:https://www.cnblogs.com/shiyublog/p/13514963.html
Copyright © 2011-2022 走看看