深拷贝和浅拷贝19.5.8

自动调用拷贝构造函数情况:

 

1.用类的一个对象去初始化另一个对象;

cat cat1;

cat cat2(cat1);

2.用类的一个对象去初始化另一个对象的另一种形式(赋值运算符)

cat cat2=cat1;

3.对象作为函数参数传递时,调用拷贝构造函数

f(cat a){}

cat b;

f(b);

4.如果函数的返回值是类的对象,函数调用返回时,调用拷贝构造函数

cat f()

{

cat a;

……

return a;

}

cat b;

b=f();

浅拷贝会出现释放问题:因为都指向同一个对象

浅拷贝是对原数组或对象的引用

深拷贝是对原数组或对象作一个新的创建,开辟了新的内存

意义:深拷贝可以避免改变新数组或对象时,改变了原数组或对象;

一般的用系统默认的浅拷贝就够用了

 

如果出现指向堆内存的指针,就需要自定义深拷贝构造函数,为对象创建新的空间,否则会出现野指针。

深拷贝同时复制了资源空间——开辟空间大小内容

这样就不会新旧都指向同一个内存地址

 

https://zhuanlan.zhihu.com/p/26282765(好文,还需研读)

https://blog.csdn.net/weixin_41910848/article/details/82144671

 

所谓 深浅拷贝

对于仅仅是复制了引用(地址),换句话说,复制了之后,原来的变量和新的变量指向同一个东西,彼此之间的操作会互相影响,为 浅拷贝

而如果是在堆中重新分配内存,拥有不同的地址,但是值是一样的,复制后的对象与原来的对象是完全隔离,互不影响,为 深拷贝

 

深浅拷贝 的主要区别就是:复制的是引用(地址)还是复制的是实例。

当数据成员是指针,要做深复制

/*

*深浅拷贝构造函数

*/

#include "pch.h"

#include <iostream>

#include <cstring>

using namespace std;

class A {

public:

       A(){

       }

       A(int age,char* cname) {

              this->age = age;

              this->name = new char[100];

              strcpy(this->name, cname);

       }

public:

       int age;

       char* name;

};

int main()

{

       char cname[100] = "hello";

       char c = 'K';

       A a(10, cname);

       A b = a;

       cout << "a:" << a.age << "  " << a.name << endl;

       cout << "b:" << b.age << "  " << b.name << endl;

       b.age = 1;

       b.name[0] = c;

       cout << "a:" << a.age << "  " << a.name << endl;

       cout << "b:" << b.age << "  " << b.name << endl;

       system("pause");

}

属于浅拷贝,就是后来改变的可以改变初始值,因为两者指针虽然是不同的,但指针所str的地址相同

     

// TestCopy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

/*

*深浅拷贝构造函数

*/

#include "pch.h"

#include <iostream>

#include <cstring>

using namespace std;

class A {

public:

       A(){

       }

       A(int age,char* cname) {//浅复制构造函数

              this->age = age;

              this->name = new char[100];

              strcpy(this->name, cname);

       }

       A(A& obj) {  //深复制构造函数

              this->age = obj.age;

              this->name = new char[100];

              if (name != 0) {

                     strcpy(this->name, obj.name);

              }

       }

~A{

delete str}

public:

       int age;

       char* name;

};

int main()

{

       char cname[100] = "hello";

       char c = 'K';

       A a(10, cname);

       A b = a;

       cout << "a:" << a.age << "  " << a.name << endl;

       cout << "b:" << b.age << "  " << b.name << endl;

       b.age = 1;

       b.name[0] = c;

       cout << "a:" << a.age << "  " << a.name << endl;

       cout << "b:" << b.age << "  " << b.name << endl;

       system("pause");

}

 


 

拷贝构造函数:

#include <iostream>

#include <stdlib.h>

#include <stdio.h>

#include <cmath>

using namespace std;

class complex{

    public:

    float real_number,imaginary_number;

    complex();

    complex(complex&);//拷贝构造函数声明

    void display()

    {

        cout<< "复数值:"<<sqrt(pow(real_number,2)+pow(imaginary_number,2)) << endl;

    }

};

complex::complex(){

real_number=4;

imaginary_number=3;    

}

complex::complex(complex& other){

    real_number= other.real_number;

    imaginary_number=other.real_number;

}

int main(){    

    complex c;

    cout<<c.real_number<<" "<<c.imaginary_number<<endl;

    c. display();

    complex c2=c;

    cout<<c2.real_number<<" "<<c2.imaginary_number<<endl;

    c2.display();

    return 0;

}

 

complex c2=c;//这种格式的拷贝,结果不对

另一种方式: 

结果正确

    complex c3(c);

    c3.real_number=6;

    c3.imaginary_number=8;

    c3. display();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值