• C++拷贝构造函数


    拷贝构造函数

    拷贝构造函数:是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象

    拷贝构造函数还在另二个方面使用:

    1.当函数的形参是类的对象, 调用函数时, 进行形参与实参结合时使用。这时要在内存新建立一个局部对象, 并把实参拷贝到新的对象空间

    中。

    2.当函数的返回值是类对象, 函数执行完成返回调用者时使用。理由也是要建立一个临时对象中,再返回调用者。因为局部对象在离开建立

    它的函数时就消亡了,不可能在返回调用函数后继续生存,所以在处理这种情况时,编译系统会在调用函数的表达式中创建一个无名临时对

    象,该临时对象的生存周期只在函数调用处的表达式中。所谓return对象, 实际上是调用拷贝构造函数把该对象的值拷入临时对象空间。如果

    返回的是变量, 处理过程类似,只是不调用构造函数。

    2.拷贝构造函数的形参类型一定是引用类型,否则将引起无穷构造过程!!!

    只有构造函数和拷贝构造函数可以用列表方式初始化,因为对象只能被构建一次,其成员变量也只能构建一次

    如果不想对象被拷贝或者赋值,将拷贝构造函数和赋值函数设置为私有并且delect,外部就无法拷贝和赋值

    class SeqList
    {
        private:
    	int data[SEQ_ INIT_ SIZE];
    	int maxsize;
    	int cursize;
    	SeqList (const SeqList& seq) = delete; // cl1
    	SeqList& operator=(const SeqList& seq) = delete; // C11
        public:
        SwqList() {}
    
    };
    int main()
    {
        SeqList seqa;
    	SeqList seqb (sega) ;//error
    	SeqList seqc;
    	seqc=seqb;       //error
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    深拷贝和浅拷贝

    浅拷贝 (影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用.

    深拷贝 (深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的.

    浅拷贝和深拷贝之间的区别:浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到

    目标对象。

    类的成员变量中如果包含指针或者文件指针,如果使用默认拷贝构造函数和默认赋值函数可能会出现重复释放内存和内存泄漏(浅拷贝)

    所以需要自己设计拷贝构造函数和赋值函数**(深拷贝)**

    class SeqList
    {
        int* data;
    	int maxsize;
    	int cursize;
    public:
    	SeqList():data (NULL),maxsize(SEQ_INIT_SIZE), cursize(0)
    	{ data = (int*)malloc(sizeof(int) * maxsize); }
        
    	~SeqList()
    	{ 
             free (data) ;
    		data = NULL;
        }
        
    	SeqList (const SeqList& seq)//浅拷贝
    	{
    		data = seq. data;
    		maxsize = seq. maxsize; 
             cursize = seq. cursize ;
        }
    	SeqList& operator= (const SeqList& seq)//赋值
    	{
    		if (this != &seq)
            {
                 data = seq. data;
    			maxsize = seq. maxsize;
                 cursize = seq. cursize; 
            }
    		return *this;
        }
    };
    int main()
    {
    	SeqList seqa;
    	SeqList seqb;
        
    	seqb = seqa;//改写了seqa data指针的指向到seqb的申请的空间,程序结束时会释放两遍seqb申请的空间,并且seqa申请的空间没有被释放,内存泄漏
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    改写后

    class SeqList
    {
        int* data;
    	int maxsize;
    	int cursize;
    public:
    	SeqList():data (NULL),maxsize(SEQ_INIT_SIZE), cursize(0)
    	{ data = (int*)malloc(sizeof(int) * maxsize); }
        
    	~SeqList()
    	{ 
             free (data) ;
    		data = NULL;
        }
        
    	SeqList (const SeqList& seq)//深拷贝
    	{
    		data = (int*)malloc(sizeof(int) * seq. maxsize) ;
    		memcpy (data,seq.data,sizeof(int) * seq. cursize) ;
    
    		maxsize = seq. maxsize; 
             cursize = seq. cursize ;
        }
    	SeqList& operator= (const SeqList& seq)//赋值
    	{
    		if (this != &seq)
            {
                 free(data);//先释放原有的空间
                 data = (int*)malloc(sizeof(int) * seq. maxsize) ;
                 memcpy (data,seq.data,sizeof(int) * seq. cursize) ;
                
    			maxsize = seq. maxsize; 
                 cursize = seq. cursize; 
            }
    		return *this;
        }
    };
    int main()
    {
    	SeqList seqa;
    	SeqList seqb;
        seqa.SeqList(seqb);
        seqb = seqa;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
  • 相关阅读:
    C#.NET 国密SM3 HASH 哈希 与JAVA互通 ver:20230803
    2022年mvnrepository跳过人机验证
    【文档智能】多模态预训练模型及相关数据集汇总
    字符串的扩展
    基于springboot实现“漫画之家”系统项目【项目源码+论文说明】
    北京十大靠谱律师事务所最新排名(2022前十推荐)
    锁执行的过程
    【C++】从零开始的CS:GO逆向分析2——配置GLFW+IMGUI环境并创建透明窗口
    Linux命令之getfacl和setfacl命令
    火绒安全个人版使用体验
  • 原文地址:https://blog.csdn.net/kb1122333/article/details/126156578