zoukankan      html  css  js  c++  java
  • 拷贝构造函数(深拷贝vs浅拷贝)

    拷贝构造函数(深拷贝vs浅拷贝)

    类对象之间的初始化是由类的拷贝构造函数完毕的。它是一种特殊的构造函数,它的作用是用一个已知的对象来初始化还有一个对象。假设在类中没有显式地声明一个拷贝构造函数。那么,编译器将会自己主动生成一个默认的拷贝构造函数,该构造函数完毕对象之间的位拷贝。位拷贝又称浅拷贝。

    一、拷贝构造函数定义格式

    类名::拷贝构造函数名(类名& 引用名)

    比如:

    Tdate ::Tdate(Tdate & d); //形參是一个对象的引用

    CString( const CString & stringSrc ); //形參是一个const的对象引用

    二、通常在下述三种情况下。须要用拷贝初始化构造函数:

    1)明白表示由一个对象初始化还有一个对象时;如Cdate day3(d1);

    2)当对象作为函数实參传递给函数形參时;如fun(Cdate day);

    3)当对象作为函数的返回值,创建一个暂时对象时。

    浅拷贝和深拷贝

    浅拷贝仅仅对对象数据成员进行简单的赋值复制操作,在某些状况下,类内成员变量须要动态开辟堆内存,假设实行位拷贝,也就是把对象里的值全然复制给还有一个对象,如A=B。这时。假设B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现执行错误。

    深拷贝和浅拷贝能够简单理解为:假设一个类拥有资源。当这个类的对象发生复制过程的时候。资源又一次分配,这个过程就是深拷贝。反之,没有又一次分配资源。就是浅拷贝。

    以下举个深拷贝的样例。

    #include "stdafx.h"
    #include <iostream>
    #include <string>
    #include <stdio.h>
    using namespace std;
    class CClass
    {
    public:
    	CClass (char *cName="",int snum=0);
    	~CClass()
    	{cout<<"析构班级:"<<pname<<endl;
    	delete  pname;
    	}
    	void Print();
    private:
    	char *pname;
    	int num;
    };
    
    CClass::CClass(char *cName,int snum)
    {
    	int length = strlen(cName);
    	pname = new char[length+1];
    	if (pname!=0)         //pname!=NULL
    	strcpy(pname,cName);
    	num=snum;
    	cout<<"创建班级:"<<pname<<endl;
    }
    
    void CClass::Print()
    {
    	cout<<pname<<"班的人数为:"<<num<<endl;
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	CClass c1("计算机061班,56);
    	CClass c2 (c1);
    	c1.Print();
    	c2.Print(); 
    	//system("pause");
    	return 0;
    }

    c1、c2内存分配情况(深拷贝) 


    CClass(CClass &p);  //自己定义拷贝构造函数声明
    //加入自己定义拷贝构造函数
    CClass::CClass(CClass &p)
    {
    	pname = new char[strlen(p.pname )+1];
    	if (pname!=0)
    		strcpy(pname,p.pname);
    	num=p.num ;
    	cout<<"创建班级的拷贝:"<<pname<<endl;
    }

    执行结果:

    创建班级:计算机061班

    创建班级的拷贝:计算机061班

    计算机061班班的人数为:56

    计算机061班班的人数为:56

    析构班级:计算机061班

    析构班级:计算机061班 



  • 相关阅读:
    python基础之入门
    C#直接删除指定目录下的所有文件及文件夹(保留目录)
    删除Oracle文件、注册表
    WinRAR 激活码(KEY)
    用C#读取txt文件的方法(转)
    c# 生成 xml 文件
    Asp.Net 文件下载1——流下载(适用于大文件且防盗链)(转)
    Asp.Net异常:"由于代码已经过优化或者本机框架位于调用堆栈之上,无法计算表达式的值"的解决方法
    响应在此上下文中不可用 asp.net
    Ajax实现局部刷新
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5206755.html
Copyright © 2011-2022 走看看