C++中使用类(重载,友元函数,转换函数等)


12点半了。好久没更新C++博文了。把一个章节看完了。接下来说下C++里的操作符重载和以后的内容。时间晚了,可能打字没打好。望大家见谅。

C++中有个operator操作符概念。如果想重载+运算符,那么需要写成operator+()。一般两个数相加是这么调用的:

a = b+c; == a = b.operator+(c);

当调用操作符,会有一个隐式的调用。把自己的对象作为操作符的对象。然后显示调用参数c。

重点介绍友元函数。因为重载了运算符后可能出现类似:

a = 1.5 + c;

此时按照上面的说法。1.5不是一个对象。无法完成操作,这时候就需要友元函数了,其实友元函数就是类的非成员函数,不会隐式的将自身对象也作为参数。

然后贴三段代码,注释写的还算详细。大家可以复制后去运行下看下结果。代码是从C++Primer Plus里抄过来的。

mytime0.h

#ifndef MYTIME0_H_
#define MYTIME0_H_
#include <iostream>
class Time
{
private:
	int hours;
	int minutes;
public:
	Time();
	Time(int h, int m = 0);
	void AddMin(int m);
	void AddHr(int h);
	void Reset(int h = 0, int m = 0);
	Time Sum(const Time & t)const;
//	接下来时重载+运算符的函数
	Time operator+(const Time & t)const;	
	void Show()const;
//	重载-运算符的函数
	Time operator-(const Time & t)const;
//	重载*运算符的函数
	Time operator*(double n)const;
//	友元函数  类似 a+b 的原型是 a.operator+(b); 所以如果 5*a 则5没有那个重载的函数,这时就不能使用类的成员函数了,需要友元函数来进行操作,类友元函数也就是非成员函数
	friend Time operator*(double m, const Time & t){return t * m;}	//内联函数,调用该类的成员函数,这里也就是上面那个函数。
//	友元函数。对于那些非成员重载操作符函数来说,操作符左面的操作数对应函数的第一个参数。类似 c = a+b 类似于 c = operator+(a,b)
	friend  std::ostream & operator<<(std::ostream & os, const Time & t);
};

#endif
mytime0.cpp
#include <iostream>
#include "mytime0.h"

Time::Time()
{
	hours = minutes = 0;
}

Time::Time(int h, int m)
{
	hours = h;
	minutes = m;
}

void Time::AddMin(int m)
{
	minutes += m;
	hours += minutes / 60;
	minutes %= 60;
}

void Time::AddHr(int h)
{
	hours += h;
}

void Time::Reset(int h, int m)
{
	hours = h;
	minutes = m;
}

Time Time::Sum(const Time & t)const
{
	Time sum;
	sum.minutes = minutes + t.minutes;
	sum.hours = hours + t.hours + sum.minutes/60;
	sum.minutes %= 60;
	return sum;
}

// 重载加号运算符的版本
Time Time::operator+(const Time & t)const
{
	Time sum;
	sum.minutes = minutes + t.minutes;
	sum.hours = hours + t.hours + sum.minutes/60;
	sum.minutes %= 60;
	return sum;
}

Time Time::operator-(const Time & t)const
{
	Time diff;
	int tot1, tot2;
	tot1 = t.minutes + 60 * t.hours;
	tot2 = minutes + 60 * hours;
	diff.minutes = (tot2 - tot1) % 60;
	diff.hours = (tot2 - tot1) / 60;
	return diff;
}

Time Time::operator*(double n)const
{
	Time result;
	long totalminutes = hours * n * 60 + minutes * n;
	result.hours = totalminutes / 60;
	result.minutes = totalminutes % 60;
	return result;
}

std::ostream & operator<<(std::ostream & os, const Time & t)
{
	os << t.hours << "hours, " << t.minutes << " minutes";
	return os;
}

void Time::Show()const
{
	std::cout << hours << " hours, " << minutes << " minutes";
	
}

//usetime0.cpp
#include <iostream>
#include "mytime0.h"

int main()
{
	using std::cout;
	using std::endl;
	Time planning;
	Time coding(2, 40);
	Time fixing(5, 55);
	Time total;

	cout << "planning time = ";
	planning.Show();
	cout << endl;
	
	cout << "coding time = ";
	coding.Show();
	cout << endl;

	cout << "fixing time = ";
	fixing.Show();
	cout << endl;
	
//	total = coding.Sum(fixing);
//	重载加号运算符的版本
	total = coding + fixing;
	cout << "coding + fixing = ";
	total.Show();
	cout << endl;

	Time morefixing(3 ,20);
	cout << "more fixing time = ";
	morefixing.Show();
	cout << endl;
	total = morefixing.operator+(total);
	cout << "morefixing.operator+(total) = ";
	total.Show();
	cout << endl;

	Time aida(3, 35);
	Time tosca(2, 48);
	Time temp;

	cout << "Aida and TOsca:\n";
	cout << aida <<"; " << tosca << endl;
	temp = aida + tosca;		// operator+()
	cout << "Aida + Tosca: " << temp << endl;
	temp = aida*1.17;
	cout << "Aida *1.17: " << temp << endl;
	cout << "10 * Tosca: " << 10 * tosca << endl;

	return 0;
}
然后接下来说下类的强制转换和自动转换。

类的自动转换就是,如果你定义了一个只接受一个参数的构造函数,那么在调用构造函数时,如果碰到匹配的参数,直接可以将一个基本类型转换为相应的类类型。其中有几种隐式转换的情况。

1.将某个对象初始化为某个值时。

2.将某个值赋值某个对象。

3.将某值传递给接收某对象参数的函数时。

4.返回值被声明为某个对象的函数返回一个某值时。

5.以上情况中,如果另一个值可以转化为某值时。

使用explicit关键字可以强制使用显式构造函数,可以避免把某值转化为某对象。

如果想进行相反的转换,那么就需要使用C++操作符函数-------转换函数。转换函数是用户自定义的强制类型转换。使用转换函数得注意以下三点:

1.转换函数必须是类方法。

2.转换函数不能指定返回类型。

3.转换函数不能有参数。

同样的,也上三段代码。

stonewt.h
#ifndef STONEWT_H_
#define STONEWT_H_
class Stonewt
{
private:
	enum{Lbs_per_stn = 14};
	int stone;
	double pds_left;
	double pounds;
public:
	Stonewt(double lbs);
	Stonewt(int stn, double lbs);
	Stonewt();
	~Stonewt();
	void show_lbs()const;
	void show_stn()const;

	// 转换函数,将对象转换为内置类型
	operator int()const;
	operator double()const;
};

#endif
stonewt.cpp

#include <iostream>
using std::cout;
#include "stonewt.h"

Stonewt::Stonewt(double lbs)
{
	stone = int(lbs)/Lbs_per_stn;
	pds_left = int(lbs)%Lbs_per_stn + lbs - int(lbs);
	pounds = lbs;
}

Stonewt::Stonewt(int stn, double lbs)
{
	stone = stn;
	pds_left = lbs;
	pounds = stn * Lbs_per_stn + lbs;
}

Stonewt::Stonewt()
{
	stone = pounds = pds_left = 0;
}

Stonewt::~Stonewt()
{
}

void Stonewt::show_stn()const
{
	cout << stone << " stone." << pds_left << " pounds\n";
}

void Stonewt::show_lbs()const
{
	cout << pounds << " pounds\n";
}

// 转换方法	不带参数,不带返回值类型
Stonewt::operator int() const
{
	return int(pounds+0.5);
}

Stonewt::operator double() const
{
	return pounds;	
}
stone.cpp

#include <iostream>
using std::cout;
#include "stonewt.h"
void display(const Stonewt st, int n);
int main()
{
	Stonewt pavarotti = 260;		//调用构造函数,因为260能转化为浮点型
	Stonewt wolfe(285.7);		//类似Stonewt wolfe = 285.7;
	Stonewt taft(21,8);

	cout << "The tenor weighted ";
	pavarotti.show_stn();
	cout << "THe detective weighted ";
	wolfe.show_stn();
	cout << "The President weighed ";
	taft.show_lbs();
	pavarotti = 256.8;			//构造函数进行初始化
	taft = 325;				//和 taft = Stonewt(325);一样
	cout << "After dinner, the tenor weighed ";
	pavarotti.show_stn();
	cout << "After dinner, the president weighed ";
	taft.show_lbs();
	display(taft, 2);
	cout << "The wrestler weighted even more.\n";
	display(422, 2);			//将422转化乘 Stonewt对象
	cout << "No stone left unearned\n";

	// 使用转换函数将类对象转化为基本类型
	Stonewt poppins(9, 28);
	double p_wt = poppins;
	cout << "COnvert to double => ";
	cout << "Poppins: " << p_wt << " pounds.\n";
	cout << "Convert to int => ";
	cout << "Poppins: " << int(poppins) << " pounds.\n";
	return 0;
}

void display(const Stonewt st, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << "Wow! ";
		st.show_stn();
	}
}

好了,写完就要1点了。准备休息,周末继续更新。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值