使用类
2009-8-12
1
.操作符重载(
operator
overloading
)
操作符重载是一种形式的
C++
多态。操作符函数的格式如下:
operator op
(argument-list)
如:
operator +( const T& t); t =
t1 + t2;
该函数将隐式地使用
t1
(因为它调用了方法),而显示地使用
t2
对象(因为它被作为参数传递)来计算总和。替代形式为
d =
t1.operator+ (t2)
;
1.1
重载的限制
ü
重载后的操作符必须至少有一个操作数是用户定义的类型,这将防止用户为标准类型重载操作符。
ü
使用操作符时不能违反操作符原来的句法规则。例如,不能将求模操作符(
%
)重载成一个操作数。同样,不能修改操作符的优先级。
ü
不能定义新的操作符。
ü
不能重载下面的操作符:
l
sizeof .
.* :: ?:
typeid const_cast dynamic_cast
reinterpret_cast static_cast
ü
以下操作符只能通过成员函数进行重载:
l
=
()
[ ] ->
2
.友元
友元为
C++
提供了另一种形式的访问权限。友元有
3
种:
l
友元函数;友元类;友元成员函数
通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限。类的友元函数是非成员函数,其访问权限与成员函数相同。由于只有类声明可以决定哪一个函数是友元,因此类声明仍然控制了哪些函数可以访问私有数据,所以,友元不会违背
OOP
原则。友元函数是类扩展接口的组成部分。类方法和友元是表达类接口的两种不同机制。
只有在类声明中的原型中才可以使用
friend
关键字;只有类方法才会使用类限定符,友元函数不使用类限定符。
2009-8-12
3
.类的自动转换和强制类型转换
只接受一个参数的构造函数定义了从参数类型到类类型的转换。如果使用关键字
explicit
限定了这种构造函数,则它只能使用显式转换,否则也可以用于隐式转换。
类
Stonewt
有以下构造函数:
Stonewt(double
lbs);
Stonewt(int stn,
double lbs);
则可以这样构造类型变量:
Stonewt myCat;
myCat = 19.6;
程序将使用构造函数
Stonewt(double)
来创建一个历史的
Stonewt
对象,并将
19.6
作为初始化值。随后,采用成员赋值方式将该临时对象的内容复制到
myCat
中。这一过程称为隐式转换,因为它是自动执行的,不需要显式强制类型转换。为了避免意外的类型转换,
C++
实现新增了一个关键字(
explicit
),用来关闭这种特性:
explicit
Stonewt(double lbs);
3.1
转换函数
构造函数只用于从某种类型到类类型的转换。要进行相反的转换,必须使用特殊的
C++
操作符函数——转换函数。转换函数形式如下:
operator
typeName( );
转换函数必须符合以下几个条件:
l
转换函数必须是类方法
l
转换函数不能指定返回类型
l
转换函数不能有参数
如
operator double( );
operaor
int( );
示例代码:
//
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
);
~
Time();
Time(
const
Time
&
t);
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
;
//
inline definition
friend Time
operator
*
(
double
n,
const
Time
&
t)
{
return
t
*
n;
}
friend std::ostream
&
operator
<<
(std::ostream
&
os,
const
Time
&
t);
};
#endif
//
mytime.cpp
#include
"
mytime.h
"
Time::Time()
{
hours
=
minutes
=
0
;
}
Time::Time(
int
h,
int
m)
{
hours
=
h;
minutes
=
m;
}
Time::
~
Time()
{
std::cout
<<
"
desconstructor called.
"
<<
std::endl;
}
Time::Time(
const
Time
&
t)
{
std::cout
<<
"
copy constructor called.
"
<<
std::endl;
hours
=
t.hours;
minutes
=
t.minutes;
}
void
Time::AddHr(
int
h)
{
hours
=
hours
+
h;
}
void
Time::AddMin(
int
m)
{
minutes
=
minutes
+
m;
hours
=
hours
+
minutes
/
60
;
minutes
=
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
=
sum.minutes
%
60
;
return
sum;
}
Time Time::
operator
-
(
const
Time
&
t)
const
{
Time sub;
long
tot1,tot2;
tot1
=
t.minutes
+
t.hours
*
60
;
tot2
=
minutes
+
hours
*
60
;
sub.minutes
=
(tot1
-
tot2)
%
60
;
sub.hours
=
(tot1
-
tot2)
/
60
;
return
sub;
}
Time Time::
operator
*
(
double
mult)
const
{
Time result;
result.minutes
=
minutes
*
mult;
result.hours
=
hours
*
mult
+
result.minutes
/
60
;
result.minutes
=
result.minutes
%
60
;
return
result;
}
std::ostream
&
operator
<<
(std::ostream
&
os,
const
Time
&
t)
{
os
<<
t.hours
<<
"
hours,
"
<<
t.minutes
<<
"
minutes.
"
;
return
os;
}
//
usemytime.cpp
#include
<
iostream
>
#include
"
mytime.h
"
int
main()
{
using
std::cout;
using
std::endl;
Time t1(
3
,
35
);
Time t2(
2
,
48
);
Time temp;
cout
<<
"
t1 and t2 :\n
"
;
cout
<<
t1
<<
"
;
"
<<
t2
<<
endl;
temp
=
t1
+
t2;
cout
<<
"
t1 + t2:
"
<<
temp
<<
endl;
temp
=
t1
*
1.17
;
cout
<<
"
t1 * 1.17:
"
<<
temp
<<
endl;
cout
<<
"
10 * t2:
"
<<
10
*
t2
<<
endl;
t2
=
Time(
2
,
57
);
return
0
;
}