运算符重载
-
cout 是 ostream 类的对象,cin 是 istream 类的对象,要想达到这个目标,就必须以全局函数(友元函数)的形式重载<<和>>,否则就要修改标准库中的类,这显然不是我们所期望的。
-
以全局函数的形式重载>>,使它能够读入两个 double 类型的数据,并分别赋值给复数的实部和虚部:
istream & operator>>(istream &in, complex &A){
in >> A.m_real >> A.m_imag;
return in;
}
istream 表示输入流,cin 是 istream 类的对象,只不过这个对象是在标准库中定义的。之所以返回 istream 类对象的引用,是为了能够连续读取复数。
- C++规定,下标运算符
[ ]
必须以成员函数的形式进行重载。该重载函数在类中的声明格式:返回值类型 & operator[ ] (参数);
或者const 返回值类型 & operator[ ] (参数) const;
使用第一种声明方式,[ ]不仅可以访问元素,还可以修改元素。使用第二种声明方式,[ ]只能访问而不能修改元素,在实际开发中,我们应该同时提供以上两种形式,这样做是为了适应 const 对象,因为通过 const 对象只能调用 const 成员函数,如果不提供第二种形式,那么将无法访问 const 对象的任何元素。
- 自增++和自减--都是一元运算符,它的前置形式和后置形式都可以被重载
- 内存管理运算符 new、new[]、delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数。一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内存时才会重载
- 以成员函数的形式重载 new 运算符:
void * className::operator new( size_t size ){
//TODO:
}
- 以全局函数的形式重载 new 运算符
void * operator new( size_t size ){
//TODO:
}
两种重载形式的返回值相同,都是void 类型,并且都有一个参数,为size_t类型。在重载 new 或 new[] 时,无论是作为成员函数还是作为全局函数,它的第一个参数必须是 size_t 类型。size_t 表示的是要分配空间的大小,对于 new[] 的重载函数而言,size_t 则表示所需要分配的所有空间的总和。**
- delete 运算符也有两种重载形式。:
- 以类的成员函数的形式进行重载
void className::operator delete( void *ptr){
//TODO:
}
- 以全局函数的形式进行重载:
void operator delete( void *ptr){
//TODO:
}
两种重载形式的返回值都是 void 类型,并且都必须有一个 void 类型的指针作为参数,该指针指向需要释放的内存空间。
如果类中没有定义 new 和 delete 的重载函数,那么会自动调用内建的 new 和 delete 运算符。
- C++中,类型的名字(包括类的名字)本身也是一种运算符,即类型强制转换运算符。类型强制转换运算符是单目运算符,也可以被重载,但只能重载为成员函数,不能重载为全局函数。经过适当重载后,
(类型名)对象
这个对对象进行强制类型转换的表达式就等价于**对象.operator 类型名()
**,即变成对运算符函数的调用。
总结
重载运算符()、[]、->、或者赋值运算符=时,只能将它们重载为成员函数,不能重载为全局函数。
运算符重载的实质是将运算符重载为一个函数,使用运算符的表达式就被解释为对重载函数的调用。
运算符可以重载为全局函数。此时函数的参数个数就是运算符的操作数个数,运算符的操作数就成为函数的实参。运算符也可以重载为成员函数。此时函数的参数个数就是运算符的操作数个数减一,运算符的操作数有一个成为函数作用的对象,其余的成为函数的实参。运算符可以重载为全局函数,然后声明为类的友元
必要时需要重载赋值运算符=,以避免两个对象内部的指针指向同一片存储空间。
网友评论