在C++面向对象程序设计中,经过构造函数对对象进程初始化,它能够为对象在计算机内存中开辟内存空间,也能够为对象的数据成员提供初始值。构造函数时一个与类同名,没有返回值的特殊成员函数,每当建立一个对象时(包括使用new动态建立对象),编译系统就会自动调用构造函数。构造函数像类之外的通常函数和类成员函数同样,能够重载和带缺省参数,构造函数的重载为对象的生成提供了各类灵活的手段。ios
构造函数分为缺省构造函数(默认构造函数)和用户自定义构造函数。当程序员没有定义构造函数时,系统就会提供一个无参的缺省构造函数,若是用户自定义了一个构造函数,编译器提供的缺省构造函数就自动消失了。程序员
拷贝构造函数的功能是一个已有的对象来初始化一个被建立的同类的对象,是一种特殊的构造函数,具备通常构造函数的全部特性,其形参是本类对象的引用。用户能够根据本身实际问题的须要定义特定的拷贝构造函数,以实现同类对象之间数据成员的传递。若是用户没有声明类的拷贝构造函数,系统就会自动生成一个缺省拷贝构造函数,这个缺省拷贝构造函数的功能是把初始的每一个数据成员的值都复制到新创建的对象中。拷贝构造函数的声明以下:编程
类名(类型 & 对象名);数组
class people安全
{函数
public:学习
void dipalay()this
{spa
}设计
private:
int a;
char*name;
};
调用拷贝构造函数有如下三种状况:
(1)用类的一个对象去初始化另外一个对象时。
(2)对象做为函数参数传递时,调用拷贝构造函数
(3)若是函数的返回值是类的对象,函数调用返回时,调用拷贝构造函数。
拷贝就是复制,建立副本。假设有对象A,A有属性t1,t2。那么,我经过拷贝A,获得B,B应该也有属性t1,t2,且A、B两个对象的每一个属性,都应该是相同的。
对于基本类型的属性t1,拷贝是没有疑义的。简单将值复制一份,就达到了拷贝的效果。而对于引用类型的属性t2来讲,拷贝就有了两层含义。
第一层是,我只是将t2引用的地址复制一份给B的t2,确实达到了属性相同的效果,能够理解为实现了拷贝,可是事实上,两个对象中的属性t2对应的是同一个对象。在B对象上对t2所指向的对象进行操做,就会影响到A对象中的t2的值。
第二层是,我将A的t2所指向的对象,假设为o1,完整复制一份,假设为o2,将新的o2的地址给B的t2。也达到了复制的效果,且对B的t2所指向的o2进行操做,不会影响到A的t2所指向的o1。
拷贝的两层含义,对应了浅拷贝和深拷贝的概念,作了第一层,就是浅拷贝,作到第二层,就是深拷贝。
基于以上内容,很容易能够想到,浅拷贝比深拷贝要更快,可是,从拷贝的意义上来看,浅拷贝相较于深拷贝,要欠缺一点。
总结一下:
浅拷贝:位拷贝,拷贝构造函数,赋值重载
多个对象共用同一块资源,同一块资源释放屡次,崩溃或者内存泄漏
深拷贝:每一个对象共同拥有本身的资源,必须显式提供拷贝构造函数和赋值运算符。
简而言之:深拷贝和浅拷贝能够简单理解为:若是一个类拥有资源,当这个类的对象发生复制过程的时候,资源从新分配,这个过程就是深拷贝,反之,没有从新分配资源,就是浅拷贝。
实例以下:
#include <iostream>using namespace std;
class CopyDemo{public: CopyDemo(int pa,char *cstr) //构造函数,两个参数 { this->a = pa; this->str = new char[1024]; //指针数组,动态的用new在堆上分配存储空间 strcpy(this->str,cstr); //拷贝过来 }
//没写,C++会自动帮忙写一个复制构造函数,浅拷贝只复制指针,以下注释部分 //CopyDemo(CopyDemo& obj) //{ // this->a = obj.a; // this->str = obj.str; //这里是浅复制会出问题,要深复制 //}
CopyDemo(CopyDemo& obj) //通常数据成员有指针要本身写复制构造函数,以下 { this->a = obj.a; // this->str = obj.str; //这里是浅复制会出问题,要深复制 this->str = new char[1024];//应该这样写 if(str != 0) strcpy(this->str,obj.str); //若是成功,把内容复制过来 }
~CopyDemo() //析构函数 { delete str; }
public: int a; //定义一个整型的数据成员 char *str; //字符串指针};
int main(){ CopyDemo A(100,"hello!!!");
CopyDemo B = A; //复制构造函数,把A的10和hello!!!复制给B cout <<"A:"<< A.a << "," <<A.str << endl; //输出A:100,hello!!! cout <<"B:"<< B.a << "," <<B.str << endl; //输出B:100,hello!!!
//修改后,发现A,B都被改变,缘由就是浅复制,A,B指针指向同一地方,修改后都改变 B.a = 80; B.str[0] = 'k';
cout <<"A:"<< A.a << "," <<A.str << endl; //输出A:100,kello!!! cout <<"B:"<< B.a << "," <<B.str << endl; //输出B:80,kello!!!
return 0;}
根据上面实例能够看到,浅复制仅复制对象自己(其中包括是指针的成员),这样不一样被复制对象的成员中的对应非空指针会指向同一对象,被成员指针引用的对象成为共享的,没法直接经过指针成员安全地删除(由于若直接删除,另外对象中的指针就会无效,造成所谓的野指针,而访问无效指针是危险的;除非这些指针有引用计数或者其它手段确保被指对象的全部权);
而深复制在浅复制的基础上,连同指针指向的对象也一块儿复制,代价比较高,可是相对容易管理。
小结:
深拷贝和浅拷贝最根本的区别在因而否真正获取一个对象的复制实体,而不是引用。
假设B复制了A,修改A的时候,看B是否发生变化:
若是B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
若是B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不一样的值)
浅拷贝(shallowCopy)只是增长了一个指针指向已存在的内存地址,
深拷贝(deepCopy)是增长了一个指针而且申请了一个新的内存,使这个增长的指针指向这个新的内存,
使用深拷贝的状况下,释放内存的时候不会由于出现浅拷贝时释放同一个内存的错误。
若是你想更好的提高你的编程能力,学好C语言C++编程!弯道超车,快人一步!
【C语言C++学习企鹅圈子】,分享(源码、项目实战视频、项目笔记,基础入门教程)
欢迎转行和学习编程的伙伴,利用更多的资料学习成长比本身琢磨更快哦!
编程学习书籍:
编程学习视频:
原文连接:https://mp.weixin.qq.com/s/emgZO229CTrtiJidAojpHA