• C++之浅拷贝、深拷贝、拷贝构造函数、拷贝赋值运算符、自定义的深拷贝函数应用总结(二百二十九)


    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

    优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

    人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

    更多原创,欢迎关注:Android系统攻城狮

    欢迎关注Android系统攻城狮

    1.前言

    本篇目的:理解C++之拷贝类对象到this指针应用。

    1. 浅拷贝(Shallow Copy):
      浅拷贝是指简单地复制对象的成员变量的值。在浅拷贝中,只复制指针或基本数据类型的值,而不会创建新的动态内存或复制指针所指向的数据。这导致多个对象共享相同的内存,可能引发潜在的问题,例如内存释放或修改数据时的冲突。

    2. 深拷贝(Deep Copy):
      深拷贝是指复制整个对象及其动态分配的内存。在深拷贝中,会创建一个新的对象,并为新对象的成员变量分配独立的内存,以复制原始对象的数据。这样可以确保每个对象拥有独立的内存空间,从而避免了共享数据的问题。

    3. 拷贝构造函数(Copy Constructor):
      拷贝构造函数是类的特殊成员函数,用于创建一个新对象,该新对象是通过复制现有对象的数据来初始化的。拷贝构造函数通常以引用形式接受一个同类型的对象作为参数,并从参数对象中复制数据到新对象。拷贝构造函数常用于对象的初始化、传递对象给函数或返回对象时进行复制操作。

    4. 拷贝赋值运算符(Copy Assignment Operator):
      拷贝赋值运算符是另一个特殊成员函数,用于将一个对象的数据复制给另一个已存在的对象。通常以赋值运算符(=)表示,并在函数体内执行适当的数据复制操作。拷贝赋值运算符允许对象之间完成数据的拷贝和替换,使一个对象能够取代另一个对象的数据。

    5. 自定义的深拷贝函数(Custom Deep Copy Function):
      自定义的深拷贝函数是用户自行编写的函数,用于实现对于类对象的深度复制。这种函数通常通过自己分配新的内存,并复制原始对象的成员变量内容到新分配的内存中。自定义的深拷贝函数可以在没有默认的拷贝构造函数或拷贝赋值运算符的情况下,实现深度复制。

    6. 通过指针进行拷贝(Copy by Pointer):
      通过指针进行拷贝是一种在类的拷贝操作中,复制指针本身的值,而不是复制指针指向的数据。这意味着多个指针将指向相同的数据,从而可能导致数据修改引起的冲突。这种方式通常不是推荐的拷贝方式,除非确保指向的数据不会在拷贝对象之间发生改变。

    7. 移动语义(Move Semantics):
      移动语义是一种优化技术,用于在对象转移时避免不必要的内存复制。通过使用移动构造函数和移动赋值运算符,对象的资源(如动态分配的内存)可以在转移后被接收方使用,而不需要进行复制。这在提高程序性能和减少资源占用方面是有益的。

    2.应用实例

    v1.0 浅拷贝

    #include 
    
    class MyClass {
    public:
        int value;
    
        MyClass(int val = 0) : value(val) {}
    
        void printValue() const {
            std::cout << "Value: " << value << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(10);
        MyClass obj2 = obj1; // 浅拷贝
    
        obj1.printValue(); // 输出: Value: 10
        obj2.printValue(); // 输出: Value: 10
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    v2.0 深拷贝

    #include 
    #include  // for memcpy
    
    class MyClass {
    public:
        int* value;
    
        MyClass(int val = 0) {
            value = new int(val);
        }
    
        ~MyClass() {
            delete value;
        }
    
        MyClass(const MyClass& other) {
            value = new int;
            memcpy(value, other.value, sizeof(int));
        }
    
        void printValue() const {
            std::cout << "Value: " << *value << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(10);
        MyClass obj2 = obj1; // 深拷贝
    
        obj1.printValue(); // 输出: Value: 10
        obj2.printValue(); // 输出: Value: 10
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    v3.0 拷贝构造函数

    #include 
    
    class MyClass {
    public:
        int value;
    
        MyClass(int val = 0) : value(val) {}
    
        MyClass(const MyClass& other) : value(other.value) {}
    
        void printValue() const {
            std::cout << "Value: " << value << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(10);
        MyClass obj2(obj1); // 使用拷贝构造函数
    
        obj1.printValue(); // 输出: Value: 10
        obj2.printValue(); // 输出: Value: 10
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    4.0 拷贝赋值运算符

    #include 
    
    class MyClass {
    public:
        int value;
    
        MyClass(int val = 0) : value(val) {}
    
        MyClass& operator=(const MyClass& other) {
            if (this != &other) {
                value = other.value;
            }
            return *this;
        }
    
        void printValue() const {
            std::cout << "Value: " << value << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(10);
        MyClass obj2;
        obj2 = obj1; // 使用拷贝赋值运算符
    
        obj1.printValue(); // 输出: Value: 10
        obj2.printValue(); // 输出: Value: 10
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    v5.0 自定义的深拷贝函数

    #include 
    
    class MyClass {
    public:
        int* value;
    
        MyClass(int val = 0) {
            value = new int(val);
        }
    
        ~MyClass() {
            delete value;
        }
    
        void deepCopyFrom(const MyClass& other) {
            *value = *other.value;
        }
    
        void printValue() const {
            std::cout << "Value: " << *value << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(10);
        MyClass obj2;
        obj2.deepCopyFrom(obj1); // 使用自定义的深拷贝函数
    
        obj1.printValue(); // 输出: Value: 10
        obj2.printValue(); // 输出: Value: 10
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    v6.0 通过指针进行拷贝

    #include 
    
    class MyClass {
    public:
        int* value;
    
        MyClass(int val = 0) {
            value = new int(val);
        }
    
        MyClass(const MyClass& other) {
            value = new int(*other.value);
        }
    
        ~MyClass() {
            delete value;
        }
    
        void printValue() const {
            std::cout << "Value: " << *value << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(10);
        MyClass obj2 = obj1; // 通过指针进行拷贝
    
        obj1.printValue(); // 输出: Value: 10
        obj2.printValue(); // 输出: Value: 10
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    v7.0 移动语义

    #include 
    
    class MyClass {
    public:
        int* value;
    
        MyClass(int val = 0) {
            value = new int(val);
        }
    
        MyClass(MyClass&& other) : value(other.value) {
            other.value = nullptr;
        }
    
        ~MyClass() {
            delete value;
        }
    
        void printValue() const {
            std::cout << "Value: " << *value << std::endl;
        }
    };
    
    int main() {
        MyClass obj1(10);
        MyClass obj2 = std::move(obj1); // 移动语义
    
        obj1.printValue(); // 这里会输出一个未定义的值(因为已移动)
        obj2.printValue(); // 输出: Value: 10
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    v8.0 将对象other的内容复制到当前对象中(即this指针)

    ```cpp
    #include 
    #include 
    
    class MyClass {
    public:
        int value;
    
        void copyFrom(const MyClass& other) {
            memcpy(this, &other, sizeof(MyClass));
        }
    };
    
    int main() {
        MyClass obj1;
        obj1.value = 10;
    
        MyClass obj2;
        obj2.copyFrom(obj1);
    
        std::cout << "obj2.value: " << obj2.value << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    1.优点:
    使用memcpy函数将&other对象的内存内容复制到this指针所指向的内存中。这样做的目的是实现对象之间的值复制,包括成员变量的值以及可能存在的虚函数表指针等。

    2.缺点:
    虽然使用memcpy可以将对象的内存内容直接复制到目标对象,但这种方式可能会导致未定义行为。这是因为memcpy是对内存进行字节级别的复制,无法处理对象中的特殊情况,如动态分配的内存、虚函数表指针等。因此,对于自定义的类,更推荐使用逐个复制成员变量的方式来实现对象之间的值复制,以确保复制的正确性和安全性。例如:

    void copyFrom(const MyClass& other) {
        this->value = other.value;
        // 在实际的代码中,可能还需要逐个复制其他成员变量
    }
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    Java内卷,仅凭这份10w字Java面试合集我已拿下15个offer
    个人网站制作 Part 25 添加实时聊天功能 | Web开发项目添加页面缓存
    leetcode 二叉树的公共近祖先
    HighTec快捷键(Keys)设置位置
    读写分离--mysql主从复制配置
    jQuery注册事件的发展历程(简单/bind/delegate/on)
    AOP打印日志参数和耗时
    ZZNUOJ_用C语言编写程序实现1231:画棋盘(附完整源码)
    根据表名称快速查询表所有字段是否包含特定数据筛选
    基于Jsp的OA企业人事管理系统【论文、数据库设计、源码、开题报告】
  • 原文地址:https://blog.csdn.net/u010164190/article/details/133150284