C/C++ 浅拷贝和深拷贝的实例详解

针对题目“C/C++ 浅拷贝和深拷贝的实例详解”,我将为您提供一份完整的攻略。

什么是拷贝

在程序设计中,我们经常使用拷贝操作,将一个对象的内容复制到另一个对象中。在C/C++中,拷贝操作可以是浅拷贝或深拷贝,两者的区别在于拷贝时是否复制该对象所指向的堆内存。

浅拷贝

浅拷贝(Shallow Copy)是指拷贝一个对象时,只复制其值及其指针,而不会复制指针所指向的内存,因此拷贝完成后的对象和原对象会共享同一块内存。

示例1

#include <iostream>
using namespace std;

class Person {
public:
    int age;
    char *name;

    Person(int age, char *name) {
        this->age = age;
        this->name = name;
    }

    void display() {
        cout << "age: " << age << endl;
        cout << "name: " << name << endl;
    }
};

int main() {
    char *name = "John";
    Person p1(18, name);
    p1.display();

    Person p2 = p1; // 浅拷贝
    p2.display();

    // 修改p1的name
    p1.name[0] = 'M';

    p1.display();
    p2.display();

    return 0;
}

在上面的代码中,我们定义了一个Person类,其中有两个成员变量agename。我们创建了一个名为p1Person对象,并将其名字设置为"John"。然后我们对p1进行了浅拷贝操作,将其赋值给了一个新的Person对象p2。接下来,我们修改了p1的名字为"Mohn",输出p1p2的信息,得到的结果如下:

age: 18
name: John
age: 18
name: John
age: 18
name: Mohn
age: 18
name: Mohn

可以看到,修改了p1的姓名之后,p2的名字也跟着改变了,这就是浅拷贝的特点。

深拷贝

深拷贝(Deep Copy)是指拷贝一个对象时,不仅复制其值及其指针,还会复制指针所指向的内存,因此最终得到的对象和原对象所指向的内存地址不同。

示例2

#include <iostream>
#include <cstring>
using namespace std;

class Person {
public:
    int age;
    char *name;

    Person(int age, char *name) {
        this->age = age;
        this->name = new char[strlen(name) + 1];
        strcpy(this->name, name);
    }

    Person(const Person &p) { // 深拷贝
        age = p.age;
        name = new char[strlen(p.name) + 1];
        strcpy(name, p.name);
    }

    void display() {
        cout << "age: " << age << endl;
        cout << "name: " << name << endl;
    }

    ~Person() {
        delete[] name;
    }
};

int main() {
    char *name = "John";
    Person p1(18, name);
    p1.display();

    Person p2 = p1; // 深拷贝
    p2.display();

    // 修改p1的name
    p1.name[0] = 'M';

    p1.display();
    p2.display();

    return 0;
}

在上面的代码中,我们对Person类进行了修改,添加了一个拷贝构造函数,用于实现深拷贝。然后我们创建了一个名为p1Person对象,并将其名字设置为"John"。然后我们对p1进行了深拷贝,将其赋值给了一个新的Person对象p2。接下来,我们 修改了p1的名字为"Mohn",输出p1p2的信息,得到的结果如下:

age: 18
name: John
age: 18
name: John
age: 18
name: Mohn
age: 18
name: John

可以看到,修改了p1的姓名之后,p2的名字并没有跟着改变,这是因为p1p2指向的是不同的地址,它们之间不存在共享的情况。

小结

以上是关于浅拷贝和深拷贝的实例详解,浅拷贝只是简单地对指针进行复制,导致不同的对象指向了同一块内存地址,而深拷贝则是将指针所指向的内存一同进行复制,保证复制出来的对象是独立的。在实际的开发过程中,为了避免这样的错误,我们应该尽量使用深拷贝。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C/C++ 浅拷贝和深拷贝的实例详解 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言中%c与%s的区别与划分详解

    C语言中%c与%s的区别与划分详解 在C语言中,%c和%s是格式化输出的常见控制字符,这两个字符在使用时有所不同。 %c的用法 %c表示输出一个字符,一般和变量类型char搭配使用。在使用%c输出时,必须提供一个字符型参数。 以下是一个示例: #include <stdio.h> int main() { char letter = ‘a’; p…

    C 2023年5月22日
    00
  • win7系统提示”OXC0000102”的错误代码而无法将请求的数据放入内存的解决方法

    “OXC0000102″错误代码的解决方法 概述 当你在使用Win7系统时,如果遇到了错误代码“OXC0000102”,你就会发现自己无法完成所需的操作,提示中表示你的数据无法放入内存。 这个错误一般是由于系统文件损坏或者硬件故障导致的,解决这个问题需要我们进行一些操作。 解决方法 以下是解决OXC0000102错误代码的方法: 1. 恢复系统 通过系统恢复…

    C 2023年5月24日
    00
  • Hibernate缓存详解

    Hibernate缓存详解 Hibernate缓存是指将常用的数据缓存在内存中,以便于快速读取和更新。Hibernate缓存可以分为一级缓存和二级缓存两种。一级缓存是指SessionFactory级别的缓存,二级缓存是指应用程序级别的缓存。下面分别介绍一级缓存和二级缓存的细节。 一级缓存 Hibernate的一级缓存默认是开启的,每个Session都有自己的…

    C 2023年5月22日
    00
  • 深入解析C++编程中线程池的使用

    深入解析C++编程中线程池的使用 什么是线程池? 线程池是一种用来集中处理线程的机制。线程池内包含多个线程,它们可以处理分配给线程池的任务。线程池在系统启动时就被初始化,一直运行到系统关闭。 为什么需要使用线程池? 线程池的好处是可以优化系统性能,通过重复利用已存在的线程,避免了频繁创建和销毁线程的开销。并且线程池可以缓解程序因为大量线程占用系统资源,导致系…

    C 2023年5月22日
    00
  • C++ 中类对象类型的转化的实例详解

    C++ 中类对象类型的转化的实例详解 什么是类型转换? 类型转换是将数据从一种数据类型转换为另一种数据类型的过程。在 C++ 中,有几种类型转换的方式: 隐式类型转换:在表达式中,某些情况下,C++ 会自动将一种类型转换为另一种类型。例如,int x = 10; float y = x; 在将 int 类型赋值给 float 类型时,C++ 会自动完成数据类…

    C 2023年5月22日
    00
  • C语言函数返回指针

    C语言中的函数可以返回不同的数据类型,包括指针类型。函数返回指针类型可以让我们更加灵活地操作内存,提高代码的重用性和可维护性。 在函数定义的时候,我们需要用指针类型作为返回值类型,并在函数体中返回指向目标数据的指针。以下是函数返回指针的基本语法: int* myFunction() { int* ptr = malloc(sizeof(int)); *ptr…

    C 2023年5月9日
    00
  • 代码讲解C++继承和派生

    这里我就来详细讲解一下“代码讲解C++继承和派生”的完整攻略。 1. C++继承 C++中的继承是指从一个类中派生出另一个类,具体实现方式为在派生类的定义中使用“:”后面跟上基类的名称。 1.1 基类和派生类的定义 下面是一个基类的定义: class Shape { public: virtual void draw() = 0; virtual doubl…

    C 2023年5月24日
    00
  • Java多线程连续打印abc实现方法详解

    Java多线程连续打印abc实现方法详解 在Java中,实现多线程有许多种方法。本攻略将会详细讲解一种实现多个线程连续打印abc的方法。 代码实现 既然是多线程,那么自然要用到Thread类。本例中,我们将定义三个线程打印a、b、c。因为需要保证abc交替打印,所以还需要使用wait()和notify()方法实现线程间的通信。 class PrintABC …

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部