(一三二)类的三种常见技术

本文详细阐述了C++中运算符重载的实现方式,包括<<、>>运算符的使用,以及如何正确处理类对象与基本类型的相互转换。同时,文章还讨论了构造函数和转换函数的运用,特别强调了使用new和delete进行内存管理的重要性,以及如何避免内存泄漏。通过实例解析,帮助读者掌握C++中对象操作的关键技巧。

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

重载<<、>>运算符:

例如:ostream& operator<<(ostream&, const Player& name);

其中:

ostream类表示cout等,也支持写入文件的ofstream类。同理,也可以换位istreamifstream类(但要把重载运算符也换为>>);

 

Player&表示类对象的引用,之所以用const进行限定,原因在于为了即可以支持被const限定的对象,也可以防止传递的引用被修改;

 

③假如类有返回需要值的类方法(例如某个函数返回某个私有成员),那么就不必将其作为友元函数(获得调用私有成员的权限);否则,必须将其设置为友元函数;

 

Player是类名。

 

 

 

 

转换函数:

转换函数有两种形式:

①把非类对象(如基本类型)转换为类对象;

 

②把类对象,转换为基本类型。

 

 

关于第一种类型转换,把非类对象转换为类对象,是通过使用构造函数(只有一个参数、或者其他参数都是默认参数时)。

例如,Player a=5;

假如Player类有一个构造函数:Player(int ){.....},

那么其流程是这样的:

 

创建一个临时对象(参数为5,调用构造函数)——》采用逐成员复制的方式,将临时对象赋值给对象a

 

注意:在第二步逐成员复制的过程中,既不调用 复制构造函数(虽然他创建了一个临时对象给对象a进行初始化) ,也不调用 赋值运算符(虽然有赋值符号,即使有PlayerPlayer::operator=(const char*m)这样的函数存在) ,调用的是符合条件的 构造函数 。


构造函数:初始化对象时,参数是非同类对象;

复制构造函数:初始化对象时,参数是同类对象(且只有一个);

赋值运算符:非初始化时,遇见赋值符号使用。


另外提一下:

初始化对象的时候必然调用构造函数(如果参数是对象则调用复制构造函数);

在其他情况下,才会调用例如赋值运算符等。

 

 

 

关于第二种类型转换,把类对象转为非类对象。

假如有类对象Player a;

使用int b=a; 时,将调用转换函数。

 

转换函数的格式为:operator 类型名(无参数);

例如:

operator int()

{

return id;

}

就是返回对象的私有成员id的值,并将其传递给int类型变量a

 

 

另外,为了防止隐式自动应用转换函数,可以将转换函数/构造函数加上关键字explicit(英文意思是显式的),当这样使用的时候,除非使用强制类型转换,否则不会隐式的自动调用转换函数/构造函数,将类对象和基本类型之间互转。

 

加关键字的例子如:

① explicit Player(int a); ——构造函数加关键字

② explicit operator int(); ——转换函数加关键字

 

 

强制类型转换的方式有:

Player a;  int(a);————强制使用int类型转换函数

 

int a; Player b= Player(a); ——强制使用构造函数,将a作为参数使用创建临时对象。

 

 

 

 

构造函数使用new的类:

如果类使用new运算符来分配类成员指向的内存,在设计时应采用一些预防措施(因为编译器无法帮你忙),预防措施有以下几条:

①对于指向内存是由new分配的每一个类成员,都应该在析构函数使用delete依次释放这些由new分配的内存;

 

②如果析构函数使用delete来释放内存,那么每个构造函数都应该使用new来分配内存,或者指向空指针(nullptr,因为空指针可以被delete);

 

new对应deletenew[]对应delete[],应该所有构造函数 和析构函数都应该统一;

 

④如果构造函数使用new,那么也应该定义一个使用new来分配内存的复制构造函数(这样避免让两个对象的类成员指向同一个内存地址);

 

⑤应定义一个重载赋值运算符的类成员函数。其方法如下:

函数头:类名类名::operator = (cosnt 类名& mm)

函数定义:防自己赋值自己——if( this==&mm) return *this;

指针——先delete,再用new分配内存,然后strcpy拷贝内容。

基本类型——按值传递

返回:*this

例如:

Player& Player::operator=(const Player& mm)
{
	if (this == &mm)return *this;	//防止自己赋值给自己
	delete[] name;	//delete现有指针
	name = new char[strlen(mm.name) + 1];	//由new分配内存
	strcpy_s(name, strlen(mm.name) + 1, mm.name);	//复制指针指向的地址的内容
	id = mm.id;		//基本类型按值传递
	return *this;	//返回是*this
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值