首页 > 其他分享 >25. 深浅拷贝

25. 深浅拷贝

时间:2024-11-16 17:48:15浏览次数:3  
标签:25 School name void school 深浅 Student 拷贝 string

一、深浅拷贝问题

  在 C++ 中,对象的拷贝可以分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。

  浅拷贝 是指当一个对象拷贝另一个对象时,只是简单地复制了对象的各个成员变量的值,包括指向其他对象的指针。这意味着,如果源对象和目标对象中的成员变量是指针类型,那么浅拷贝只会复制指针的值,而不是指针指向的数据。因此,源对象和目标对象将共享相同的指针指向的数据,这可能会导致潜在的问题,比如当一个对象被销毁时,它可能会释放资源,导致另一个对象中的指针悬空,又比如两个对象将共享同一块内存,如果一个对象改变了那块内存的内容,另一个对象也会受到影响。默认情况下,编译器会为类生成浅拷贝构造函数和浅拷贝赋值运算符。

  深拷贝 是指当一个对象拷贝另一个对象时,不仅复制了对象的各个成员变量的值,而且还复制了这些成员变量所指向的数据。这意味着,如果源对象和目标对象中的成员变量是指针类型,那么深拷贝会分配新的内存,为指针指向的数据创建一个新的副本,并将指针指向这个新副本。因此,源对象和目标对象将拥有独立的资源,新旧对象之间不会共享任何非静态成员,互不影响。

  在 C++ 中,默认的拷贝构造函数和拷贝赋值运算符通常执行浅拷贝。如果你需要实现深拷贝,你需要在你的类中自定义拷贝构造函数和拷贝赋值运算符,以确保正确地复制所有成员变量所指向的数据。

二、什么是浅拷贝

  浅拷贝 只是简单地复制对象的所有成员变量,包括指针。如果对象的成员变量中有动态分配的内存(如指针指向的内存),则浅拷贝只是复制了指针本身,而不是它所指向的内存。这意味着两个对象现在指向同一块内存区域。
在这里插入图片描述

class School
{
private:
    string name;
    string address;

public:
    School(void);
    School(string name, string address);

    void showInfo(void);

    string getName(void);
    void setName(string name);

    string getAddress(void);
    void setAddress(string address);
};

School::School(void) : name(""), address("") {}

School::School(string name, string address) : name(name), address(address) {}

void School::showInfo(void)
{
    cout << "School{name: " << name << ", address: " << address << "}" << endl;
}

string School::getName(void)
{
    return name;
}

void School::setName(string name)
{
    this->name = name;
}

string School::getAddress(void)
{
    return address;
}

void School::setAddress(string address)
{
    this->address = address;
}
class Student
{
private:
    string name;
    int age;
    School *school;

public:
    Student(void);
    Student(string name, int age);

    void showInfo(void);

    string getName(void);
    void setName(string name);

    int getAge(void);
    void setAge(int age);

    School * getSchool(void);
    void setSchool(School *school);
};

Student::Student(void) : name(""), age(0), school(new School()) {}
Student::Student(string name, int age) : name(name), age(age) {}

void Student::showInfo(void)
{
    cout << "Studet{name: " << name << ", age: " << age << ", school: " << school->getName() << "}" << endl;
}

string Student::getName(void)
{
    return name;
}

void Student::setName(string name)
{
    this->name = name;
}

int Student::getAge(void)
{
    return age;
}

void Student::setAge(int age)
{
    this->age = age;
}

School * Student::getSchool(void)
{
    return school;
}

void Student::setSchool(School *school)
{
    this->school = school;
}
#include <iostream>

using namespace std;

int main(void)
{
    School *school = new School("友枝小学", "京都府京都中京区");

    Student s1("木之本樱", 10);
    s1.setSchool(school);
    s1.showInfo();

    Student s2(s1);
    s2.setAge(12);
    s2.getSchool()->setName("友枝中学");
    s2.showInfo();

    s1.showInfo();

    delete school;

    return 0;
}

三、什么是深拷贝

  深拷贝不仅会复制对象的所有成员变量,还会为指针所指向的内存分配新的内存,并将内容复制到新的内存区域。这样,两个对象就有各自独立的内存区域。如果我们想要实现深拷贝,需要自己重写类的拷贝构造函数。
在这里插入图片描述

  在 Student 类中重写拷贝构造函数和析构函数。

class Student
{
private:
    string name;
    int age;
    School *school;

public:
    Student(void);
    Student(string name, int age);
    Student(const Student &student);
    ~Student(void);

    void showInfo(void);

    string getName(void);
    void setName(string name);

    int getAge(void);
    void setAge(int age);

    School * getSchool(void);
    void setSchool(School *school);
};

Student::Student(void) : name(""), age(0), school(new School()) {}
Student::Student(string name, int age) : name(name), age(age) , school(new School()) {}

Student::Student(const Student &student) : name(student.name), age(student.age)
{
    school = new School(student.school->getName(), student.school->getAddress());
}

Student::~Student(void)
{
    if (school != nullptr)
    {
        delete school;
    }
}

void Student::showInfo(void)
{
    cout << "Studet{name: " << name << ", age: " << age << ", school: " << school->getName() << "}" << endl;
}

string Student::getName(void)
{
    return name;
}

void Student::setName(string name)
{
    this->name = name;
}

int Student::getAge(void)
{
    return age;
}

void Student::setAge(int age)
{
    this->age = age;
}

School * Student::getSchool(void)
{
    return school;
}

void Student::setSchool(School *school)
{
    this->school = school;
}

  修改 main() 函数:

int main(void)
{
    School *school = new School("友枝小学", "京都府京都中京区");

    Student s1("木之本樱", 10);
    s1.setSchool(school);
    s1.showInfo();

    Student s2(s1);
    s2.setAge(12);
    s2.getSchool()->setName("友枝中学");
    s2.showInfo();

    s1.showInfo();

    return 0;
}

标签:25,School,name,void,school,深浅,Student,拷贝,string
From: https://blog.csdn.net/flurry_heart/article/details/143777646

相关文章

  • 20222315 2024-2025-1 《网络与系统攻防实验六实验》实验六实验报告
    1、实验内容本实践目标是掌握metasploit的用法。指导书参考Rapid7官网的指导教程。https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/下载官方靶机Metasploitable2,完成下面实验内容。(1)前期渗透①主机发现(可用Aux中的arp_sweep,search一下就可以use......
  • ssm125四六级报名与成绩查询系统+jsp(论文+源码)_kaic
     毕业设计(论文)题目:四六级报名与成绩查询系统的设计与实现      摘 要互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对四六级报名信息管理混......
  • 20222406 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    202224062024-2025-1《网络与系统攻防技术》实验五实验报告1.实验内容对网站进行DNS域名查询,包括注册人、IP地址等信息,还通过相关命令查询IP地址注册人及地理位置。尝试获取QQ好友IP地址并查询其地理位置。使用nmap对靶机环境扫描,获取靶机IP活跃状态、开......
  • ML 系列:第 25 节 — 连续概率分布 (高斯分布)
    文章目录一、说明二、关于高斯分布三、高斯分布的重要类型四、了解Python中智商分数的Z核心和概率计算一、说明高斯分布是典型的连续函数的概率分布。然而,现实中我们只能用离散形式去表述,而使用连续分布在计算机上,就是需要技巧的。二、关于高斯分布高斯分布,......
  • 20222310 2024-2025-1 《网络与系统攻防技术》实验六实验报告
    一、实验内容学习掌握Metasploit工具的使用。下载靶机Metasploitable2,完成以下实验内容。1.前期渗透(1)主机发现(可用Aux中的arp_sweep,search一下就可以use)(2)端口扫描(可以直接用nmap,也可以用Aux中的portscan/tcp等)(3)扫描系统版本,漏洞等2.Vsftpd源码包后门漏洞(21端口)3.SambaMS-R......
  • 20222423 2024-2025-1 《网络与系统攻防技术》实验六实验报告
    1.实验内容1.1内容回顾总结总而言之这周都重点在于Metasploit工具的使用时间上,对其功能和使用流程有了深入了解,也越发感叹道魔高一尺,道高一丈,好多漏洞如今的操作系统或者软件都已经修复,通过msf针对漏洞实施变得越发困难(重点点名本周的msf测试作业,让我一天都没吃上饭,基本上时间......
  • # 20222403 2024-2025-1 《网络与系统攻防技术》实验六实验报告
    1.实验内容本实践目标是掌握metasploit的用法。指导书参考Rapid7官网的指导教程。https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/下载官方靶机Metasploitable2,完成下面实验内容。(1)前期渗透①主机发现(可用Aux中的arp_sweep,search一下就可以use)......
  • InDesign 2025 for Mac(Id2025)最新激活版20.0.0
    InDesign2025具备强大的功能和灵活的扩展性,支持插件扩展,用户可以根据自身需求自定义工具和工作流程。在处理复杂排版和多页面设计时,InDesign2025注重用户界面的友好性与功能的直观性,即使是新手用户也能快速上手。InDesign2025增强了多模态图文编辑能力,使得图像与文字的结合更......
  • 20222323 2024-2025-1 《网络与系统攻防技术》实验六实验报告
    1.实验内容掌握metasploit的用法。下载官方靶机Metasploitable2,完成下面实验内容。(1)前期渗透①主机发现(可用Aux中的arp_sweep,search一下就可以use)②端口扫描:可以直接用nmap,也可以用Aux中的portscan/tcp等。③选做:也可以扫系统版本、漏洞等。(2)Vsftpd源码包后门漏洞(21端口)(3)S......
  • 20222306 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    1.实验内容(1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式该域名对应IP地址IP地址注册人及联系方式IP地址所在国家、城市和具体地理位置PS:使用whois、dig、nslookup、traceroute、以及各类在线和离线工具进行搜集......