c++细节

本文深入探讨拷贝构造函数与赋值运算符重载的实现细节,包括参数设计、深拷贝与浅拷贝的区别,以及在不同场景下如何避免自我赋值与内存泄漏。同时,解析了转换构造函数与类型转换函数的作用,帮助读者理解类型转换的机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于拷贝构造函数

1.参数应该为引用,并加上const
	如果不是引用,是传值,那么就会有一次形参和实参的拷贝,这本身又是一次拷贝构造,因此会无限循环。
	为啥加const 1.const类型对象可以用来拷贝构造2.防止修改原对象。
2.默认拷贝构造函数
	简单的赋值,浅拷贝,如果有手动开辟的堆空间,只是改变的指针指向并没有真正的复制。
什么时候回调用拷贝构造函数?
	首先明白初始化和复制的区别
	int a = 100;  //以赋值的方式初始化 初始化
	a = 200;  //赋值
	int b;  //默认初始化
	b = 29;  //赋值
	//stu1、stu2、stu3都会调用普通构造函数Student(string name, int age, float score)
	Student stu1("小明", 16, 90.5);
    Student stu2("王城", 17, 89.0);
    Student stu3("陈晗", 18, 98.0);
   
    Student stu4 = stu1;  //调用拷贝构造函数Student(const Student &stu)
    stu4 = stu2;  //调用operator=()
    stu4 = stu3;  //调用operator=()
   
    Student stu5;  //调用普通构造函数Student()
    stu5 = stu1;  //调用operator=()
    stu5 = stu2;  //调用operator=()
    四种情况会出现拷贝构造
    1.将其他对象作为参数
    Student stu1("小明", 16, 90.5);  //普通初始化
	Student stu2(stu1);  //以拷贝的方式初始化
	2.在创建对象的同时赋值
	Student stu1("小明", 16, 90.5);  //普通初始化
	Student stu2 = stu1;  //以拷贝的方式初始化
	3. 函数的形参为类类型
	4. 函数返回值为类类型
		注意:函数的返回值为引用和值的区别。如果是在函数内部创建的变量,不能返回其引用

重载=

编译器默认会重载,简单的赋值拷贝。
Array &Array::operator=(const Array &arr){  //重载赋值运算符
    if( this != &arr){  //判断是否是给自己赋值
        this->m_len = arr.m_len;
        free(this->m_p);  //释放原来的内存
        this->m_p = (int*)calloc( this->m_len, sizeof(int) );
        memcpy( this->m_p, arr.m_p, m_len * sizeof(int) );
    }
    return *this;
}
1.返回值为引用:满足连续赋值的要求
2.判断是否是自己给自己赋值,如果不加判断,free(this->m_p);  会释放自己内存
3.const 两个目的同上
4.返回*this

这里没有考虑申请内存失败的问题。
更标准的写法如下

Array &Array::operator=(const Array &arr){
	if (this != &arr){
		Array temp(arr);
		this->m_len = arr.m_len;
		int*help = this->m_p;
		this->m_p = temp.m_p;
		temp.m_p = help;
	}
	return *this;
}
用拷贝构造的方式创建一个arr的副本,让this中的m_p和副本中的m_p交换,副本会在函数调用完毕后析构。

转换构造函数

当编译器知道转换规则的时候,可以自动进行类型转换
例如:
int a = 6;
a = 7.5 + a;
先将 a 转换为 double 类型,然后与 7.5 相加,得到和为 13.5。在向整型变量 a 赋值时,将 13.5 转换为整数 13,然后赋给 a。
同理,这种转换可以用于类,前提是要让编译器知道转换规则。
例如:cmplex是复数类
Complex c1(15.6, 89.9);
Complex c2;
c2 = c1 + 29.6;
声明了转换构造函数后,c2 = c1 + 29.6;就等价于
c2 = c1 + complex(29.6);

类型转换函数

将当前类类型转换为其他类型
operator type(){
    //TODO:
    return data;
}
例如:operator double() const { return m_real; }  //转换为double类型

如果同时定义了类型转换函数和转换构造函数就会导致二义性,转换构造函数常用

Complex c1(24.6, 100);
float f = 12.5 + c1;
既可以complex(12.5)又可以将c1类型转换为double 二义性

类型转换

本质:对数据所占用的二进制位做出重新的解释,必要的时候还会修改数据,改变其二进制位,当知道转换规则的时候。
强制转换,无法对二进制位修改。(注意:这种修改是有利的,修改的不是原始数据,只是副本)

四种类型转换运算符
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值