C++中深拷贝与浅拷贝的区别

2024-04-11 23:04
文章标签 c++ 区别 拷贝 中深

本文主要是介绍C++中深拷贝与浅拷贝的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.概念

深拷贝(deep copy)和浅拷贝(shallow copy)是在编程中经常遇到的概念,尤其在处理数据结构或对象时很重要。深拷贝和浅拷贝是相对于类的成员指针变量而言的,如果类内不存在成员指针变量,就没有深拷贝和浅拷贝。

  1. 浅拷贝:在浅拷贝中,只复制了对象本身,而不复制对象内部包含的引用对象。简而言之,新对象的引用仍然指向原始对象内部的引用对象。这意味着如果你修改了新对象内部的引用对象,原始对象也会受到影响,因为它们共享相同的引用。通常,浅拷贝使用简单的赋值操作来实现。

  2. 深拷贝:深拷贝会复制对象本身以及对象内部的所有引用对象,包括引用对象内部的引用对象,以此类推。这样,原始对象和深拷贝后的对象是完全独立的,对一个对象的修改不会影响另一个对象。深拷贝通常需要递归地复制所有引用对象,确保每个对象都是全新的。

深拷贝和浅拷贝在不同情况下有不同的应用场景。通常情况下:

  • 当你希望修改一个对象时,不影响原始对象,就应该使用深拷贝。
  • 当对象较大且内部结构较为简单时,浅拷贝可能更高效

2. 浅拷贝

浅拷贝 :拷贝对象的时候,不对指针成员所指向的对象进行拷贝,而是两个对象的指针成员指向同一个对象。
示例:
class Phone
{
private:string name;
public:Phone(string name):name(name){}
};class Person
{
private:Phone* pPhone;//当一个对象里有指针类型成员时,才有必要去考虑深拷贝和浅拷贝
public:Person(){pPhone = new Phone("诺基亚plus");}Phone* getPhone(){return pPhone;}
};int main()
{Person* xiaoming = new Person();Person xiaoqiang(*xiaoming);
//因Person中没有显式的定义拷贝构造函数,所以使用默认拷贝构造函数,默认拷贝构造函数的逻辑是浅拷贝cout<<xiaoming->getPhone()<<endl;//这两个对象的phone指针应该指向同一个对象cout<<xiaoqiang.getPhone()<<endl;
}

3.深拷贝

深拷贝:需要在对象的拷贝构造函数中对成员指针所指向的对象也进行拷贝。
#include <iostream>
using namespace std;
class Phone
{string name;
public:Phone(string name):name(name){}
};class Person
{Phone* pPhone;
public:Person(){//创建一个手机pPhone = new Phone("华为");}Phone* getP(){return pPhone;}//拷贝 this --> xqPerson(const Person& other)  //const Person& other = xm;{cout<<"copy"<<endl;this->pPhone = other.pPhone;//1.找到小明的指针// other.pPhone 指针 *other.pPhone 指针指向的对象//2.按照小明的指针指向的对象 创建一个一模一样的//new Phone(*other.pPhone)//3.小强的指针 指向新对象this->pPhone = new Phone(*other.pPhone);}
};//1.系统默认的拷贝构造:浅拷贝的过程
//2.浅拷贝:类中包含了一个成员指针,只对成员指针的指向 进行赋值
int main()
{Person xm;Person xq(xm);cout<<xm.getP()<<endl;cout<<xq.getP()<<endl;return 0;
}

 

注意:
      1.系统默认的拷贝构造函数是: 浅拷贝。
      2.当类中有指针类型的成员时,才去考虑深拷贝和浅拷贝的问题。
最后的最后,希望大家点点赞,点点关注,谢谢大家!

 

这篇关于C++中深拷贝与浅拷贝的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/895410

相关文章

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C# Semaphore与SemaphoreSlim区别小结

《C#Semaphore与SemaphoreSlim区别小结》本文主要介绍了C#Semaphore与SemaphoreSlim区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、核心区别概览二、详细对比说明1.跨进程支持2.异步支持(关键区别!)3.性能差异4.API 差

C++打印 vector的几种方法小结

《C++打印vector的几种方法小结》本文介绍了C++中遍历vector的几种方法,包括使用迭代器、auto关键字、typedef、计数器以及C++11引入的范围基础循环,具有一定的参考价值,感兴... 目录1. 使用迭代器2. 使用 auto (C++11) / typedef / type alias

Java中自旋锁与CAS机制的深层关系与区别

《Java中自旋锁与CAS机制的深层关系与区别》CAS算法即比较并替换,是一种实现并发编程时常用到的算法,Java并发包中的很多类都使用了CAS算法,:本文主要介绍Java中自旋锁与CAS机制深层... 目录1. 引言2. 比较并交换 (Compare-and-Swap, CAS) 核心原理2.1 CAS

C++ scoped_ptr 和 unique_ptr对比分析

《C++scoped_ptr和unique_ptr对比分析》本文介绍了C++中的`scoped_ptr`和`unique_ptr`,详细比较了它们的特性、使用场景以及现代C++推荐的使用`uni... 目录1. scoped_ptr基本特性主要特点2. unique_ptr基本用法3. 主要区别对比4. u

C++11中的包装器实战案例

《C++11中的包装器实战案例》本文给大家介绍C++11中的包装器实战案例,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录引言1.std::function1.1.什么是std::function1.2.核心用法1.2.1.包装普通函数1.2.