mytime.h头文件
#ifndef MYTIME_H_
#define MYTIME_H_
#include<iostream>
class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddHr(int h);
void AddMin(int m);
void Reset(int h = 0, int m = 0);
Time operator+(const Time& t) const;
//直接将函数名改为运算符函数形式---并将结果作方法名即可
Time operator-(const Time& t) const;
//这里没有将返回对象设置为引用是因为,不要返回指向局部变量或临时对象的引用,因为在函数执行完后会消失
Time operator*(double n)const;
friend Time operator*(double m,const Time &t)
{ return t * m; }
//友元函数将其原型放在类声明中,并在原型声明前面加上关键字friend
//这里意味着不能在使用成员运算符来进行调用,但是其函数的访问权限和普通的成员函数一样,可以访问到私有部分
//由于他不是成员函数,所有定义实现时不用加上限定修饰符进行限定
friend std::ostream& operator<<(std::ostream& os, const Time& t);
//类继承属性让ostream引用能够指向ostream对象和ofstream对象
//只有在类声明中的原型中才能使用friend关键字
};
//在类中使用状态成员--类似标签——用于描述对象所处的状态,以及使用的是那种成员函数
//全限定名:名称空间::类::私有部分
#endif
mytime.cpp文件
#include"mytime.h"
Time::Time()
{
hours = 0;
minutes = 0;
}
Time::Time(int h, int m)
{
hours = h;
minutes = m;
}
void Time::AddHr(int h)
{
hours += h;
}
void Time::AddMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::Reset(int h, int m)
{
hours = h;
minutes = m;
}
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 totl, tot2;
totl = t.minutes + 60 * t.hours;
tot2 = minutes + 60 * hours;
diff.minutes = (tot2 - totl) % 60;
diff.hours = (tot2 - totl) / 60;
return diff;
}
Time Time::operator*(double mult)const
{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
//定义友元函数时,不用加关键字friend
std::ostream& operator<<(std::ostream& os, const Time& t)
{
os << t.hours << "hours, " << t.minutes << " minutes";
return os;//这里返回一个指向ostream的对象,用于下个表达式语句
}
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 cat;cat=19.6;--这是自动进行的
//所以只有接受一个参数的构造函数才能作为转换函数
//如果使用关键字explicit限定了构造函数,则他只能用于显示转化!!!---就是普通的类声明
//最好就是使用显示化的声明,防止二义性的错误
//这里还要说明一下,如果构造函数所匹配的类型均不符,则会进行兼容的转化
Stonewt(int stn, double lbs);
Stonewt();
~Stonewt();
void show_lbs()const;
void show_stn()const;
//注意转换函数和重载运算符函数有点相似--operator关键字
//但有三点不同:1、转换函数必须是类方法2、转换函数不能指定返回类型3、转换函数不能有参数;下列
operator int()const;
operator double() const;
//使用转换函数可以直接使用c风格式的强制类型转化或c++风格式的函数式转化
//列:long gone=(double—)poppins;long gone= int(poppins)
//同理c++11也可以将explicit关键字用于转换函数
};
#endif
stonewt.cpp文件
#include<iostream>
#include"stonewt.h"
using std::cout;
Stonewt::Stonewt(double lbs)
{
stone = int(lbs) / Lbs_per_stn;
pds_left = int(lbs) % Lbs_per_stn;
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 << pds_left;
}
void Stonewt::show_lbs() const
{
cout << pounds << "\n";
}
Stonewt::operator int()const
{
return int(pounds + 0.5);
}
Stonewt::operator double() const
{
return pounds;
}
使用类.cpp文件
#include<iostream>
#include"mytime.h"
//c++第二种多态————运算符重载可以让标准c++运算符用于类对象
//要使用重载后的运算符,要先运算符函数的特殊形式operatorop() op是运算符符号
//将运算符进行了成员函数式的重载可以利用成员函数的方法进行调用,也可以直接使用运算符表示法
//重载运算符不必是成员函数,但至少有一个操作数使用户定义的类型
//此外,不能违反运算符本来的语法规则和优先级-----P316页见不可重载符号
int main()
{
using std::cout;
using std::endl;
//c++提供另一种形式的访问权限---访问私有部分---友元:友元函数、友元类、友元成员函数
//通过让函数成为类的友元,赋予该函数与类的成员函数相同访问权限--为了解决一些特殊情况
//特别:如果要为类重载运算符,并将非类的项作为第一个操作数,则可以用友元函数来反转操作数的顺序
//这里要知道改变iostream文件的内容是一个危险的主意
Time aida(3, 35);
Time tosca(2, 48);
Time temp;
cout << "Aida and Tosca:\n";
cout << aida << ";" << tosca << endl;//要实现这条语句,cout必须返回一个指向ostream的对象
//因此cout<<aida本身就是一个cout对象
temp = aida + tosca;
//operator()函数的名称可以使用函数表达式或运算符表示来调用它
//可以使用t1=t2+t3+t4;这样的表达式来求和,因为会最终转化为一个函数调用--其实就是函数的嵌套
cout << temp << endl;
//那么现在引出一个问题:c++是如何处理基本数据类型和类类型的转化之间的问题?
//第一种构造转化函数--结合着构造函数一起的;;第二种:使用基本的成员函数---见stonewt.h文件
//如果是类要转化为其他基本类型--要使用转化函数————见stonewt.h
//思考一下如果不用转换函数,还可以怎么做?
//答案是使用可以只用成员函数(重载运算符)或友元函数类实现,只不过调用的方法不同
return 0;
}