使用类
运算符重载
- 运算符重载是一种形式的C++多态,赋予了c++运算符多重含义
重载的运算符不必是成员函数,但必须至少有一个操作数是用户定义的类型- 重载后的运算符必须至少有一个操作数是用户定义的类型,防止用户为标准类型重载运算符
- 使用运算符时不能违反运算符原来的语法规则
- 不能创建新运算符
- 不能重载的运算符
符号 | 运算符 |
---|---|
sizeof | sizeof运算符 |
. | 成员运算符 |
.* | 成员指针运算符 |
:: | 作用域解析运算符 |
?: | 条件运算符 |
typeid | RTTI运算符 |
const_cast | 强制类型转换运算符 |
dynamic_cast | 强制类型转换运算符 |
reinterpret_cast | 强制类型转换运算符 |
static_cast | 强制类型转换运算符 |
//.h文件
#ifndef MYTIME1_H_
#define MUTIME1_H_
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 operator+(const Time& t)const;
void Show() const;
}
#endif
//.cpp文件
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::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;
}
void Time::Show()const
{
cout << hours << "hours" << minutes << "minutes" << endl;
}
int main()
{
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 + fixing;
cout << "coding + fixing = ";
total.Show();
cout << endl;
Time morefixing(3, 28);
cout << "more fixing time = ";
morefixing.Show();
cout << endl;
total = morefixing.operator+(total);
cout << "morefixing.operator+(total) = ";
total.Show();
cout << endl;
return 0;
}
友元
-
c++控制对类对象私有部分的访问。通常,公有类方法提供唯一的访问途径,但限制太严格不适合特定的编程问题。c++提供了另外一种形式的访问权限
- 友元函数
- 友元类
- 友元成员函数
- 通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限
- A = B * 2.75,会被转换成下面的例子 A = B.operator*(2.75)。而反过来A = 2.75 * B,看起来是同一个意思,但程序识别不出来
- 友元函数
- 原型在类声明中,在原型声明前加上关键字friend
- 虽然需要在类声明中声明,但不是成员函数,不能用成员运算符来调用
- 访问权限和成员函数相同
- 原型在类声明中,在原型声明前加上关键字friend
friend Time operator*(double m, const Time & t);
- 定义的时候不需要加friend关键字
Time operator*(double m, const & t)
{
...
}
- 然后像上述的A * 2.75 * B就能够使用了
-
友元函数并没有违反数据隐藏的原则,看似友元机制允许非成员函数访问私有数据。但只是表达类接口的两种不同机制,可以把友元函数看作是类的拓展接口
重载运算符 -
对于很多运算符来说,可以选择使用成员函数或非成员函数来实现运算符重载。一般非成员函数是作为友元函数
-
定义运算符时,只能选择一种格式,因为两种格式都与一种表达式匹配,会出现二义性错误,导致编译错误
-
Time operator+(const Time & t) const;
friend Time operator+(consst Time & t1, const Time & t2);
类的自动转换和强制类型转换
- 可以将类定义成与基本类型或另一个类相关,使得从中类型转换为另一种类型是有意义的。
// .h文件
class Stonewt
{
private:
enum {Lbs_per_stn = 14};
int stone;
double pds_left;
double pounds;
public:
Stonewt(double lbs);
// explicit Stonewt(double lbs);
Stonewt(int stn, double lbs);
Stonewt();
~Stonewt();
void show_lbs() const;
void show_stn() const;
// 转换函数
operator int() const;
operator doubel() const;
}
// .cpp文件
Stonewt::Stonewt(double lbs)
{
...
}
Stonetn::Stonewt(int stn, double lbs)
{
...
}
Stonewt::Stonewt()
{
...
}
void Stonewt::show_stn() const
{
...
}
void Stonewt::show_lbs() const
{
...
}
Stonewt::operator int() const
{
...
}
Stonewt::operator double() const
{
...
}
Stonewt myCat;
myCat = 19.6;
- 在使用构造函数Stonetw(double)来创建一个临时的Stonewt对象,采用逐成员赋值方式将该临时对象复制到变量中。这一过程为隐式转换,属于自动转换
- 可以加上关键字explicit来关闭自动转换的特性
- 转换函数是用户定义的强制类型转换,可以像使用强制类型转换那样使用它们
Stonewt wolfe(275.7);
double host = double (wolfe);
doubel host1 = (double) wolfe