14运算符重载
C++的所有运算符都可以被重载吗?
. .* :: ?: sizeof 不能被重载
什么情况下需要考虑运算符重载?
当要把自定义类的对象用作运算符的操作数时,可以被重载的运算符中只有赋值运算符 = 和地址运算符 & 可直接用于对象的操作
运算符重载函数如何定义?
保持运算符的原有属性,作为类的成员函数或友元函数、作为一般函数
特例:( ) [ ] -> = 及类型转换运算符的重载
运算符的重载函数定义为类的成员函数
1.当该成员函数不带参数时,支持以该类对象为唯一操作数的运算
2.当该成员函数带一个参数时,支持以该类对象为左操作数、以所带参数类型的数据为右操作数的运算
运算符的重载函数定义为类的友元函数
1.当该函数带一个参数时,支持以该参数类型的对象为唯一操作数的运算
2.当该函数带两个参数时,支持以第一个参数类型的数据为左操作数、以第二个参数类型的数据为右操作数的运算
在包含对象的双目运算中,当双目运算符的左操作数不是某类的对象时,重载函数不能定义为该类的成员函数
流插入运算符<<的重载,运算符可交换性的实现(两个不同类型的操作数)
运算符重载函数的定义要保证运算无二义性
注意:
操作数是自定义类的对象或对象的引用
作为成员函数重载,没有参数
作为友元函数重载,参数为自定义类的对象或对象的引用
单目运算符重载
特殊的单目运算符++、--
以++ 为例( -- 同理) ,设b为类C的对象。。。。
前自增,如:++b
重载函数可为C的成员函数,原型为
返回值类型 operator++();
重载函数也可为C的友元函数,原型为
返回值类型 operator++(C &);
后自增,如:b++
重载函数可为C的成员函数,原型为
返回值类型 operator++(int);
b++转换为函数调用b.operator++(0)
重载函数也可为C的友元函数,原型为
返回值类型 operator++(C &, int);
b++转换为函数调用operator++(b,0)
双目运算符重载
一般双目运算符的重载要考虑两个因素:
1.被重载运算符的左操作数是什么数据类型
2.是否要保留运算符的可交换性(只针对具有可交换性的运算符而言)
双目运算符的重载可实现为
- 带有一个参数的(非静态)成员函数(左操作数必须为该类的对象或对象的引用)
- 带有两个参数的非成员函数(其参数之一必须是类的对象或对象的引用)
赋值运算符重载
赋值运算符可直接用在自定义类的对象赋值,其默认操作是逐个拷贝对象的所有数据成员
如果对象中包含动态分配的空间时,这种赋值方式就有可能出错,如
String s1("abc"),s2("def"),&s3=s1;
s1 = s2;
对象s1和s2中都只有一个数据成员str,在赋值操作后,对象s1和s2的指针str都指向了同一块数据空间(即存放了"def"的存储空间)
例子 一:复数的+、-、=运算
// 文件1:complex1.h--复数类的定义
#ifndef _COMPLEX1_H
#define _COMPLEX1_H
class Complex
{public:
Complex(double = 0.0, double = 0.0);
Complex operator+(const Complex&) const;
Complex operator-(const Complex&) const;
Complex& operator=(const Complex&);
void print() const;
private:
double real; // real part
double imaginary; // imaginary part
};
#endif
//文件2:complex1.cpp--复数类的成员函数定义
#include <iostream.h>
#include "complex1.h"
Complex::Complex(double r, double i)
{ real = r;
imaginary = i;
}
Complex Complex::operator+(const Complex
& operand2) const
{Complex sum;
sum.real = real + operand2.real;
sum.imaginary = imaginary +
operand2.imaginary;
return sum;
}
Complex Complex::operator-(const Complex
& operand2) const
{Complex diff;
diff.real = real - operand2.real;
diff.imaginary = imaginary –
operand2.imaginary;
return diff; }
Complex& Complex::operator=(const
Complex & right)
{real = right.real;
imaginary = right.imaginary;
return *this; }
void Complex::print( ) const
{cout<<'('<<real<< ", " << imaginary
<< ')'; }
//文件3: FIG13_1.cpp--主函数定义
#include <iostream.h>
#include "complex1.h"
main()
{Complex x, y(4.3, 8.2), z(3.3, 1.1);
cout << "x: ";
x.print();
cout << "\ny: ";
y.print();
cout << "\nz: ";
z.print();
x = y + z;
cout << "\n\nx = y + z:\n";
x.print();
cout << " = ";
y.print();
cout << " + ";
z.print();
x = y - z;
cout << "\n\nx = y - z:\n";
x.print();
cout << " = ";
y.print();
cout << " - ";
z.print();
cout << '\n';
return 0;}
例子二:重载运算符 ! ,以判断对象中的字符串是否为空串
//文件string.h
#if !defined __STRING__H__
#define __STRING__H__
#include <stdlib.h>
class String
{public:
String(char *m="");
~String();
//定义运算符重载成员函数原型
bool operator !( );
private:
char *str;
};
#endif
//文件String.cpp
#include <string.h>
#include "string.h"
String::String(char *m)
{str = new char[strlen(m)+1];
strcpy(str,m);
}
String::~String()
{delete [] str;}
bool String::operator !() //实现运算符重载
{if (strlen(str) == 0)
return true;
return false;
}
#include <iostream.h>
#include "String.h"
main( )
{String s1, s2("some string");
if (!s1) //括号中等价于s1.operator!()
cout<<"s1 is NULL!"<<endl;
else
cout<<"s1 is not NULL!"<<endl;
if (!s2)
cout<<"s2 is NULL!"<<endl;
else
cout<<"s2 is not NULL!"<<endl;
return 0;
}
例子三:重载流插入运算符<<和流提取运算符>>
//文件string.h
#if !defined __STRING__H__
#define __STRING__H__
#include <iostream.h>
class String
{friend ostream & operator<<(ostream
&output, String &s);
friend istream & operator>>(istream
&input, String &s);
public:
String(char *m=" ");
~String();
private:
char *str;
}; #endif
//文件string.cpp
#include <string.h>
#include "string.h"
String::String(char *m)
{str = new char[strlen(m)+1];
strcpy(str,m);
}
String::~String()
{
delete [] str;
}
//定义运算符<<和>>的重载函数
ostream & operator<<(ostream &output,
String &s)
{output << s.str;
return output;
}
istream & operator>>(istream &input,
String &s)
{char temp[1000];
cin >> temp;
delete [] s.str;
s.str = new char[strlen(temp)+1];
strcpy(s.str,temp);
return input;
}
#include "string.h"
main()
{String s1,s2;
cout << "Please input two strings: "
<< endl;
cin >> s1 >> s2;
cout << "Output is: " << endl;
cout << "s1 -- " << s1
<< endl << "s2 -- " <<s2 << endl;
return 0;
}
例子四:重载运算符+=使x+=y实现将对象y中的字符串连接到对象x的字符串后面
//文件string.h,定义类String
#if !defined __STRING__H__
#define __STRING__H__
#include <iostream.h>
class String
{friend ostream & operator<<(ostream
&output, String &s);
friend istream & operator>>(istream
&input, String &s);
public:
String(char *m="");
~String();
String & operator+=(String &s);
private:
char *str;};
#endif
//文件string.cpp,类String的实现
#include <string.h>
#include "string.h"
String::String(char *m)
{str = new char[strlen(m)+1];
strcpy(str,m);
}
String::~String()
{delete [] str;}
//定义运算符<<的重载函数
ostream & operator<<(ostream &output,
String &s)
{output<<s.str;
return output;
}
//定义运算符>>的重载函数
istream & operator>>(istream &input,
String &s)
{char temp[1000];
cin>>temp;
delete [] s.str;
s.str = new char[strlen(temp)+1];
strcpy(s.str,temp);
return input;
}
//定义运算符+=的重载函数
String &String::operator+=(String &s)
{char temp[4096]; //不是最好的实现
strcpy(temp,str);
strcat(temp,s.str);
delete []str;
str = new char[strlen(temp)+1];
strcpy(str,temp);
return *this;
}
#include "string.h"
main()
{String s1,s2;
cin>>s1>>s2; //输入字符串Wuhan和Changsha
cout<<"s1 -- "<<s1<<endl;
s1+=s2;
cout<<"s1 after s1+=s2 -- "<<s1<<endl;
return 0;
}
例子五:重载运算符+和=,使得类String的对象x、y、z可以执行表达式 x = y + z
//文件string.h,定义类String
#if !defined __STRING__H__
#define __STRING__H__
#include <iostream.h>
class String
{friend ostream & operator<<(
ostream &output, String &s);
friend istream & operator>>(
istream &input, String &s);
public:
String(char *m="");
~String();
String & operator=(String &s);
String & operator+(String &s);
private: char *str; };
#endif
//文件string.cpp,类String的实现
#include <string.h>
#include "string.h"
String::String(char *m)
{str = new char[strlen(m)+1];
strcpy(str,m);
}
String::~String()
{delete [] str; }
ostream & operator<<(
ostream &output, String &s)
{output<<s.str;
return output;
}
//定义运算符>>重载函数
istream & operator>>(
istream &input, String &s)
{
char temp[1000];
cin>>temp;
delete [] s.str;
s.str = new char[strlen(temp)+1];
strcpy(s.str,temp);
return input;
}
String &String::operator=(String &s)
{
if (&s == this) //检查是否自我赋值,非常重要
return *this;
delete []str; //释放当前对象的数据空间
str = new char[strlen(s.str)+1];
//重新分配适当大小的空间
strcpy(str, s.str);
return *this;
}
String &String::operator+(String &s)
{
static String res;
//为什么要声明res为静态对象?
char temp[4096];
strcpy(temp,str);
strcat(temp,s.str);
delete [] res.str;
res.str = new char[strlen(temp)+1];
strcpy(res.str,temp);
return res;
}
#include "String.h"
main()
{String s1,s2;
cout << "Please input two strings: "
<< endl;
cin >> s1 >> s2;
cout << "Output is: " << endl;
cout << "s1 -- " << s1 << endl;
cout << "s2 -- " <<s 2 << endl;
s1 = s1 + s2;
cout << "after s1 = s1 + s2;" << endl;
cout << "s1 -- " << s1 << endl;
return 0;
}