首页 > 编程语言 >C++浅拷贝和深拷贝

C++浅拷贝和深拷贝

时间:2024-08-13 12:49:34浏览次数:3  
标签:对象 sayHello C++ 复制 内存 拷贝 构造函数

在C++编程中,对象的拷贝是一项常见的操作。深拷贝浅拷贝是两种常用的拷贝方式,对于理解对象拷贝的内部机制和避免潜在的问题至关重要。本文将深入解析C++中的深拷贝和浅拷贝的概念、原理以及使用场景,帮助读者更好地掌握和运用这两种拷贝方式。

浅拷贝(Shallow Copy)是指在拷贝对象时,只是复制了对象中的成员变量的值的引用或指针。浅拷贝后的对象和原对象共享一份数据,修改一个对象可能会影响另一个对象。

深拷贝(Deep Copy)是指在拷贝对象时,会创建一个新的独立的对象,并复制原对象中的所有成员变量的值。深拷贝后的对象和原对象是完全独立的,修改一个对象不会影响另一个对象。

深拷贝的实现

复制构造函数(Copy Constructor):深拷贝通常通过复制构造函数来实现。复制构造函数是一种特殊的构造函数,用于在创建对象时进行拷贝初始化。在复制构造函数中,通过分配新的内存空间,并将原对象的值复制到新对象中,实现对象的深拷贝

浅拷贝的实现

默认拷贝构造函数:如果没有显式定义复制构造函数,C++会提供一个默认的复制构造函数,它执行的是浅拷贝。默认的复制构造函数将简单地将原对象的成员变量的值复制给新对象,导致新对象和原对象共享相同的数据。

接下来我们通过一个例子来理解

创建一个MyString类,封装C风格字符串(MyString::buffer)使用字符时无需分配内存和释放内存。  
#include<iostream>
#include<string.h>

using namespace std;

class MyString{
    private:
        char *buffer;
    public:
    // 构造函数
    // const char * 指向字符串的常量指针  在内存中是常量不可以修改
        MyString(const char * initstring){
            buffer=NULL;
            cout << "constructor mystring" << endl;
            if(initstring != NULL){
                // 动态分配内存
                buffer = new char[strlen(initstring)+1];
                strcpy(buffer,initstring);
                // 为新对象分配新的内存,并复制原始对象的所有数据到这个新内存中
                cout << (unsigned int*)buffer << endl;
            }
            else{
                buffer = NULL;
            }
        }
        //复制构造函数
        MyString(const MyString &copy){
            buffer = NULL;
            cout << "copy" << endl;
            if (copy.buffer != NULL){
                buffer = new char[strlen(copy.buffer)+1];
                strcpy(buffer,copy.buffer);
                cout << (unsigned int*)buffer << endl;
            }
        }
// 析构函数 ~MyString(){ cout << "delete!" << endl; if (buffer!=NULL){ delete [] buffer; } } int Getlength(){ return strlen(buffer); } const char* GetString(){ return buffer; } }; void UseString(MyString str){ cout << "usestring string is:" << str.GetString() << endl; cout << "buffer is:" << str.Getlength() << endl; } int main(){ MyString sayHello("Hello from string class"); UseString(sayHello); }

浅拷贝的问题,在Usestring中,对象sayHello被复制到形参str。UseString在传递时,被声明为按值传递(非引用传递),此时编译器执行二进制复制(整型、字符和原始指针等POD数据),此时sayHello.buffer包含的指针被复制到str中。二进制复制不复制指向的内存单元,因此sayHello和str指向同一个内存单元,当UseString()返回,形参str不在作用域,因此被销毁。当Mystring类调用析构函数的delete[]销毁给buffer的内存时,会显示sayHello的内存指向无效。

深拷贝解决,使用复制构造函数实现深拷贝,复制构造函数用于创建一个对象的副本,通过一个已经存在的对象来初始化一个新的对象。sayHello和str不指向同一个内存单元,当UseString()返回,形参str被销毁时,析构函数对复制构造函数分配的内存地址调用delete[],没有影响sayHello的内存。

标签:对象,sayHello,C++,复制,内存,拷贝,构造函数
From: https://www.cnblogs.com/qhj384343045-/p/18346436

相关文章

  • C++——构造函数和析构函数
    一、初识构造函数和析构函数简单来说,有对象生成必然会调用构造函数,有对象销毁必然会调用析构函数。构造函数的作用是初始化成员变量,是由编译器去调用的,而析构函数同理也是由编译器调用,不过他的作用则是清理。可以由下面的代码体验两个函数的使用。注意:相同点:两个函数都没有......
  • 基于Dango+微信小程序的广西东盟旅游资源信息管理系统+80003(免费领源码)可做计算机毕业
    django广西-东盟旅游资源信息管理系统小程序摘 要在社会快速发展和人们生活水平提高的影响下,旅游产业蓬勃发展,旅游形式也变得多样化,使旅游资源信息的管理变得比过去更加困难。依照这一现实为基础,设计一个快捷而又方便的基于小程序的旅游资源信息管理系统是一项十分重要并且......
  • c++ 字符串转 整形
    目前有两种string 转整形的方式std::atoi(constchar*);std::stoi(conststd::string);atoi()是c语言风格,而stoi()是c++11标准库中新增的函数两者的区别在atoi()的参数是constchar*,所以我们必须将字符串的类型从string转换为constchar类型才能够转换为int。str......
  • C++:内存管理
    C++内存管理的概念        C语言内存管理方式(malloc/free)在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。new/delete                    new/d......
  • C++:类与对象(下)
    再探构造函数        构造函数体赋值与初始化列表其实之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅式,就是初始化列表,C++规定初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,每个"成员变量"后⾯跟......
  • C++:类与对象(中)
    类的默认成员函数:        在C++中,如果你没有显式地定义某些特定的成员函数(如构造函数、析构函数、拷贝构造函数、拷贝赋值运算符和移动构造函数),那么编译器会自动生成这些函数。这些由编译器自动生成的函数被称为默认成员函数。        构造函数   ......
  • C语言和C++中的动态内存管理------malloc和free的区别
    引言:动态内存管理:需要根据具体情况来设定需要的内存大小,同时可能需要大于1Mbyte的连续空间。此时我们无法使用静态数组。原因是因为静态数据的开辟是在栈空间,其次栈空间的大小在连续分配时不能超过1Mbyte,因此引入了动态内存管理。C语言C语言中动态内存管理的有四个函数:mal......
  • SecureCoding in C and C++(二)
    经过上期的环境搭建过后,我们将正式的学习C++系列,首先要学习的是C++的一些常用的变量从编译和连接学起似乎也是不错的选择。个人总结的一句话:编译其实就是对预处理语句进行处理后,然后对语句进行处理。对预处理语句,例如:#include之类的处理方式其实就是将文件内容复制到对应......
  • C ++ 也可以搭建Web?高性能的 C++ Web 开发框架 CPPCMS + MySQL 实现快速入门案例
    什么是CPPCMS?CppCMS是一个高性能的C++Web开发框架,专为构建快速、动态的网页应用而设计,特别适合高并发和低延迟的场景。其设计理念类似于Python的Django或RubyonRails,但针对C++提供了更细粒度的控制和更高效的性能。主要特点和优点1.高性能与并发处理​Cp......
  • C++类和对象(类的定义)
    目录一·类的定义1.1类的定义格式1.2访问限定符(public、private、protected)1.3类域一·类的定义1.1类的定义格式定义类的关键字是class,类定义结束时,后面的分号不能省略。类体中的内容称为类的成员:①类中的变量称为类的属性或成员变量;②类中的函数称为类的方......