您的位置:首页 > 编程语言 > C语言/C++

C++第11章,使用类

2015-06-13 09:47 337 查看
运算符重载

operator+(argument-list)

假设有一个Saleperson类

如果a,b,c都是其对象。

a = b + c;

等价于

a = b.operator+(c)隐式的使用b,显式的使用c

a = b + c + d ;

a = b.operator+( c + d)

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

重载限制:

重载后的运算符的操作数必须有一个是用户自定义的类型,这样可以防止用户为标准类型的操作重载运算符。比如不能把-重载为两个double类型的和。而不是它们的差。

11.3友元

友元函数

友元类

友元成员函数

通过让函数成为类的友元,可以赋予该函数与类的成员函相同的访问权限。

非成员函数不是由对象调用的,它使用的所有值(包括对象)都是显式参数。

A = 2.75 * B;

与下面的非成员函数调用匹配:

A = operator*(2.75,B);

该函数的原型如下:

Time operator*(double m,const Time & t);

有一类特殊的非成员函数可以访问类的私有数据,他们被称为友元函数。

C++编程常见错误—cannot have cv-qualifier//不能有CV限定,在C++中CV指const和volatile—1、非成员函数不能有CV限定,2、静态成员函数不能有CV限定

提示:如果要为类重载运算符,并将非类的项作为其第一个操作数,则可以用友元函数来翻转操作数。

#include <iostream>
using namespace std;

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;
Time operator*(int mult)const;
friend Time operator*(int m,const Time & t);
void show()const;
};

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;
}

Time Time::operator*(int mult)const{
Time result;
result.hours = hours + mult*minutes / 60 ;
result.minutes = mult*minutes % 60 ;
return result;

}

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

Time operator*(int m,const Time & t){
Time result;
result.minutes = t.minutes * m % 60;
result.hours = t.hours + t.minutes * m / 60;
return result;
}

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.Sum(fixing) = ";
total.show();
cout << endl;

return 0;*/

Time a(1,35);
Time b;
b = 2 * a;
b.show();
}


上述对定义进行修改,也可以不使用友元函数,可以将这个友元函数编写为非友元函数

Time operator*(int m,const Time & t){
return t * m;//use t.operator*(m);
}


原来的版本显式的访问类的私有成员,所以必须是友元函数,这个版本让成员函数来处理私有值,所以不必是友元函数。

常用的友元: 重载<<运算符

要使Time类知道使用cout,必须使用友元函数。如果使用一个Time成员函数来重载<<,Time对象将是第一个操作数。这意味着必须这样使用<<

trip << cout

但是通过使用友元函数,可以像下面这样重载运算符:

void operator<<(ostream & os,const Time &t){

os << t.hours << “hours ,” << t.minutes << “minutes”;

}

但是返回类型为void,意味着无法cout << x << y 这样使用。

为此可更改为:

ostream& operator<<(ostream & os,const Time &t){

os << t.hours << “hours ,” << t.minutes << “minutes”;

return os;

}

代码很短时,应该使用内联函数。inline。一般将定义和声明放在一起。如果分开,则只在声明中使用inline即可。

11.6 类的自动转换和强制类型转换。

类型转换构造函数:

在C++中,接受一个参数的构造函数,为将类型和该参数相同的值转换为类对象提供了蓝图。

下面的构造函数用于将double类型的值转换为Stonewt类型

Stonewt(double lbs)

Stonewt myCat;

myCat = 19.6;

程序将使用19.6创造一个临时对象并且初始化。随后将赋值给myCat;这一过程称之为隐式转换,因为它是自动进行的。

只有接受一个参数的构造函数才能作为转换函数。但是如果出了第一个参数,其余形参提供了默认值,则可以用于转换。

比如

Stonewt(int a,int b = 0);则可以用于转换int

C++提供了关键字explicit用于关闭这项特性。

explicit Stonewt(int a);

仅仅关闭了隐式类型转换,但是仍然可以进行强制类型转换。

转换函数:

以上将数字转换为Stoewt对象。可以做相反的转换吗?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: