C++深拷贝与浅拷贝的区别及应用

 更新时间:2021年04月12日 11:38:57   作者:寻痴  
这篇文章主要给大家介绍了关于C++深拷贝与浅拷贝区别及应用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

浅拷贝

只是对指针的拷贝,拷贝后两个指针指向同一个内存空间;

深拷贝

对指针指向的内容进行拷贝(重新分配内存),经深拷贝后的指针是指向不同地址的指针;

因此浅拷贝释放内存的时候很容易出现因为释放两个指针而内存出错。

浅拷贝(释放时,因为多次释放出错)

只拷贝指针

	//拷贝构造函数
	Vector(const Vector<T>& v)
		:_start(nullptr)
		,_finish(nullptr)
		,_endOfStorage(nullptr)
	{
		_start=v._start;
		_finish=v._finish;
		_endOfStorage=v._endOfStorage;
	}

深拷贝

对资源进行拷贝

 Vector(const Vector<T>& v)
	
		:_start(nullptr)
		, _finish(nullptr)
		, _endOfStorage(nullptr)
	{
		size_t n = v.capacity();
		_start = new T[n];
		for (size_t i = 0; i < v.size(); ++i)
		{
			_start[i] = v[i];
		}
		_finish = _start + v.size();
		_endOfStorage = _start + n;
	}

写一个Vector的类

 template<class T>
class Vector
{
typedef T* operator;
typedef const T* const_iterator;
	iterator _start;
	iterator _finish;
	iterator _endOfStorage;
	
 public:
//构造函数
 Vector()
		:_start(nullptr)
		, _finish(nullptr)
		, _endOfStorage(nullptr)
	{}

	//析构函数
	~Vector()
	{
		if(_start)
		{
			delete[] _start;
			_star=_finish=_endOfStorage=nullptr;
		}
	}
T& operator[](size_t pos)
	{
		if (pos >= 0 && pos < size())
			return _start[pos];
	}
size_t size() const
{
	return _finish - _start;
}
 
size_t capacity() const
{
	return _endOfStorage - _start;
}


};

可以用自己编辑器,把拷贝放进去试试;

附:c++深拷贝与浅拷贝问题实例

浅拷贝:简单的赋值拷贝操作;

深拷贝:在堆区重新申请空间,再进行拷贝操作;

问题:浅拷贝会带来堆区内存被重复释放的问题,析构函数被调用多次,导致程序运行崩溃;

解决:通过深拷贝解决,在堆区重新申请内存,各自释放自己的内存,避免重复释放;

#include <iostream>

using namespace std;

class Person
{
public:
    Person() {
        cout << "Person的默认构造函数调用"<<endl;
    }
    Person(int age,int height) {
        m_Age = age;
        m_Height = new int(height);//堆区重新申请空间,进行深拷贝,手动申请,手动释放;
        cout << "Person的有参函数调用" << endl;
    }
    int m_Age;
    int *m_Height;

    //自己实现拷贝构造函数,来避免编译器的拷贝构造函数造成浅拷贝问题;
    Person(const Person& p) {
        cout << "Person拷贝构造函数" << endl;
        m_Age = p.m_Age;
        //m_Height = p.m_Height; 浅拷贝,编译器默认实现这行代码;
        m_Height = new int(*p.m_Height);//深拷贝
    }

    ~Person() {
        //析构代码,将堆区开辟数据做释放操作
        if (m_Height != NULL) {
            delete m_Height;
            m_Height = NULL;
        }
        cout << "Person的析构函数调用" << endl;
    }
};

void test01(){
    Person p1(18,160);
    cout << "p1的年龄为:" << p1.m_Age<<"p1身高为:"<<*p1.m_Height<< endl;
    Person p2(p1);//编译器默认调用拷贝构造函数,进行浅拷贝操作
    cout << "p2的年龄为:" << p2.m_Age<< "p2身高为:"<<*p2.m_Height << endl;
}

int main(){
    test01();
    system("pause");
}

程序运行结果:

总结

到此这篇关于C++深拷贝与浅拷贝区别及应用的文章就介绍到这了,更多相关C++深拷贝与浅拷贝内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解C++中的vector容器及用迭代器访问vector的方法

    详解C++中的vector容器及用迭代器访问vector的方法

    使用迭代器iterator可以更方便地解引用和访问成员,当然也包括vector中的元素,本文就来详解C++中的vector容器及用迭代器访问vector的方法,需要的朋友可以参考下
    2016-05-05
  • C++解决大数组栈内存不够问题的方法分析

    C++解决大数组栈内存不够问题的方法分析

    这篇文章主要介绍了C++解决大数组栈内存不够问题的方法,结合实例形式对比分析了C++针对大数组栈内存不足情况的常见解决方法及其优缺点,具有一定参考借鉴价值,需要的朋友可以参考下
    2018-05-05
  • C语言简明讲解变量的属性

    C语言简明讲解变量的属性

    我们知道以在 C 语言中的变量有自己的属性,只要在定义变量的时候加上“属性”关键字即可。“属性”关键字指明变量的特有意义,但是 register 关键字只是请求寄存器变量,所以不一定会成功
    2022-04-04
  • C语言之单向链表详解及实例代码

    C语言之单向链表详解及实例代码

    这篇文章主要介绍了C语言之单向链表的相关资料,及实例代码,帮助大家学习参考,,需要的朋友可以参考下
    2016-09-09
  • c++实现简单的线程池

    c++实现简单的线程池

    这里给大家介绍了C++中对于pthread线程的一个简单应用以及使用继承CDoit,实现其中的start和end,有需要的小伙伴可以参考下
    2015-11-11
  • C语言编程C++自定义个性化类型

    C语言编程C++自定义个性化类型

    这篇文章主要介绍了C语言编程中如何来自定义C++个性化类型,文中附含详细的示例代码,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-09-09
  • OpenCV轮廓检测之boundingRect绘制矩形边框

    OpenCV轮廓检测之boundingRect绘制矩形边框

    在进行文本检测时,我们常常会用矩形边框将检测到的内容框除。这篇文章主要为大家介绍的是OpenCV中能实现这一效果的函数:boundingRect,感兴趣的同学可以学习一下
    2021-12-12
  • VC程序设计小技巧20例

    VC程序设计小技巧20例

    这篇文章主要介绍了VC程序设计小技巧20例,需要的朋友可以参考下
    2014-07-07
  • C语言使用普通循环方法和递归求斐波那契序列示例代码

    C语言使用普通循环方法和递归求斐波那契序列示例代码

    这篇文章主要介绍了C语言使用普通循环方法和递归求斐波那契序列示例代码,大家参考使用吧
    2013-11-11
  • 实现posix消息队列示例分享

    实现posix消息队列示例分享

    这篇文章主要介绍了实现posix消息队列示例,学习记录锁,线程互斥量,线程条件变量,内存映射,信号,线程的综合应用,需要的朋友可以参考下
    2014-02-02

最新评论