c浅拷贝和深拷贝的区别_js中深拷贝和浅拷贝的区别

c浅拷贝和深拷贝的区别_js中深拷贝和浅拷贝的区别先考虑一种情况,对一个已知对象进行拷贝,编译系统会自动调用一种构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数。先看一个例子,有一个学生类,数据成员时学生的人数和名字:#include<iostream>usingnam…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

先考虑一种情况,对一个已知对象进行拷贝,编译系统会自动调用一种构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数。

       先看一个例子,有一个学生类,数据成员时学生的人数和名字:

#include <iostream>  
using namespace std;
 
class Student
{

private:
    int num;
    char *name;
public:
    Student();
    ~Student();
};
 
Student::Student()
{

    name = new char(20);
    cout << “Student” << endl;
 
}
Student::~Student()
{

    cout << “~Student ” << (int)name << endl;
    delete name;
    name = NULL;
}
 
int main()
{

    {// 花括号让s1和s2变成局部对象,方便测试
        Student s1;
        Student s2(s1);// 复制对象
    }
    system(“pause”);
    return 0;
}

c浅拷贝和深拷贝的区别_js中深拷贝和浅拷贝的区别

       执行结果:调用一次构造函数,调用两次析构函数,两个对象的指针成员所指内存相同,这会导致什么问题呢?name指针被分配一次内存,但是程序结束时该内存却被释放了两次,会导致崩溃!

c浅拷贝和深拷贝的区别_js中深拷贝和浅拷贝的区别
       这是由于编译系统在我们没有自己定义拷贝构造函数时,会在拷贝对象时调用默认拷贝构造函数,进行的是浅拷贝!即对指针name拷贝后会出现两个指针指向同一个内存空间。

c浅拷贝和深拷贝的区别_js中深拷贝和浅拷贝的区别

       所以,在对含有指针成员的对象进行拷贝时,必须要自己定义拷贝构造函数,使拷贝后的对象指针成员有自己的内存空间,即进行深拷贝,这样就避免了内存泄漏发生。

        添加了自己定义拷贝构造函数的例子:

#include <iostream>  
using namespace std;
 
class Student
{

private:
    int num;
    char *name;
public:
    Student();
    ~Student();
    Student(const Student &s);//拷贝构造函数,const防止对象被改变
};
 
Student::Student()
{

    name = new char(20);
    cout << “Student” << endl;
 
}
Student::~Student()
{

    cout << “~Student ” << (int)name << endl;
    delete name;
    name = NULL;
}
Student::Student(const Student &s)
{

    name = new char(20);
    memcpy(name, s.name, strlen(s.name));
    cout << “copy Student” << endl;
}
 
int main()
{

    {// 花括号让s1和s2变成局部对象,方便测试
        Student s1;
        Student s2(s1);// 复制对象
    }
    system(“pause”);
    return 0;
}

c浅拷贝和深拷贝的区别_js中深拷贝和浅拷贝的区别

        执行结果:调用一次构造函数,一次自定义拷贝构造函数,两次析构函数。两个对象的指针成员所指内存不同。
 总结:浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
再说几句:
当对象中存在指针成员时,除了在复制对象时需要考虑自定义拷贝构造函数,还应该考虑以下两种情形:
1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动通过拷贝构造函数实现;
2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝,用于返回函数调用处。
3.浅拷贝带来问题的本质在于析构函数释放多次堆内存,使用std::shared_ptr,可以完美解决这个问题。

关于std::shared_ptr的原理和实现可参考:C++笔试题之smart pointer的实现

一个完整的自定义类实现可参考:C++笔试题之String类的实现

参考链接:https://www.cnblogs.com/always-chang/p/6107437.html

深拷贝和浅拷贝的区别
16913

深浅拷贝的区别:  浅拷贝是将原始对象中的数据型字段拷贝到新对象中去,将引用型字段的“引用”复制到新对象中去,不把“引用的对象”复制进去,所以原始对象和新对象引用同一对象,新对象中的引用型字段发生变化…
 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188217.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 防火墙基础

    防火墙基础

    2021年4月15日
    149
  • ValidateRequest问题

    ValidateRequest问题1,在出现该错误的页面头部的page中加入ValidateRequest="false",那么该页面的任何一次Post提交都不会再验证提交内容的安全性。如:<%@&#160

    2022年7月2日
    21
  • pytest指定用例_测试用例怎么编写

    pytest指定用例_测试用例怎么编写前言测试用例在设计的时候,我们一般要求不要有先后顺序,用例是可以打乱了执行的,这样才能达到测试的效果.有些同学在写用例的时候,用例写了先后顺序,有先后顺序后,后面还会有新的问题(如:上个用例返回

    2022年7月31日
    4
  • Eclipse tomcat插件

    Eclipse tomcat插件

    2021年9月10日
    62
  • @scheduled注解 定时任务控制(Spring响应式编程)

    概念项目经常会用到定时任务,实现定时任务的方式有很多种,参考Spring定时任务的几种实现。在Spring框架中,实现定时任务很简单。常用的实现方式是使用注解@Schedule。@Schedule常用来实现简单的定时任务。例如凌晨1点跑批,每1小时更新订单状态等。非SpringBoot项目springmvc-servlet.xml中添加配置&amp;amp;amp;amp;lt;!–xmlns加入–&amp;amp;amp;amp;gt;…

    2022年4月16日
    162
  • shell循环读取文件拼接字符串

    shell循环读取文件拼接字符串1注意通道和重定向的区别通道会开启子shell,于是通道语句块内的变量修改是无法影响到其外的变量的,故使用重定向;2windows文件末尾是/r/n拼接来自windows系统的文件务必首先注意:[nash5camFiles]#cat-AcamFiles.ori0.863631-0.269646-0.425949^M$

    2022年7月24日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号