栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 深浅拷贝问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 深浅拷贝问题

为什么开辟到堆区:因为堆区的内存由程序员创建和释放,在函数体外也可以调用,在使用堆区的时候需要考虑拷贝时防止指针空挂的现象

浅拷贝造成的问题
#include 
#include 
using namespace std;

class Student
{
	public:
		string m_name;
		int* p_age;  // 存放年龄的指针 
		
		Student()
		{
			cout << "默认构造函数调用" << endl;
		}
		Student(string name,int age)
		{
			m_name=name;
			p_age=new int(age);  // 将age存到堆区 
			cout << "有参构造函数调用" << endl;
		}
		~Student()
		{
			if(p_age!=NULL)  // 堆区由程序员调用也需要由程序员释放 
			{
				delete(p_age);  // 释放分配的空间 
				p_age=NULL;  // 将内存指针置空 
			}
			cout << "析构函数调用" << endl;
		}
};

int main(void)
{
	Student s1("Mike",18);
	cout << "NAME:" << s1.m_name << " AGE:" << *s1.p_age << "  address:" << s1.p_age << endl;
	
	Student s2(s1);
	cout << "NAME:" << s2.m_name << " AGE:" << *s2.p_age << "  address:" << s2.p_age << endl;
	return 0;
}

这个时候出发了错误,是因为在系统建立的默认拷贝函数,将s1对象中的m_age的值完整的复制给了s2对象中的m_age的值,执行析构函数时,根据栈的规则,先进后出,释放了掉s2.m_age的值;

为什么判断s1.m_age是否为空,还会产生错误?这是因为浅复制的作用,s1.m_age的字面是不为空,但是实际指向的地址已经在s2.m_age中被释放掉了,所以产生了错误

NAME:Mike AGE:18  address:0x7d1540  // s1.m_age == s2.m_age
NAME:Mike AGE:18  address:0x7d1540


深拷贝

浅拷贝其实就是因为缺少拷贝构造函数,使用系统的默认拷贝构造函数所引发的问题

// 系统使用的默认拷贝构造函数
Student(const Student & s)
{
    m_name=s.m_name;
    p_age=s.p_age; // 仅复制值而为独立分开内存空间
}

// 自定义默认拷贝构造函数
Student(const Student & s)
{
    cout << "拷贝构造函数" << endl;
    m_name=s.m_name;
    p_age=new int(*s.p_age); // 在堆区申请地址
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982562.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号