运算符重载

运算符重载

运算符的重载实际上是通过函数重载实现的。
一般格式:
函数类型 operator 运算符名称(参数列表)
{对运算符的重载处理}
上面的重载格式中,“operator +”就是重载函数的函数名,意为对“+”运算符的重载函数
例如,想将"+"重载为对complex(复数)类的加法运算,函数原型可以为:
Complex operator + (Comples &c1, Complex &c2);

看一段代码😊

# include<iostream>
using namespace std;
class Complex
{
public:
	int real;
	int image;
	Complex()       //构造函数
	{
		real=0;
		image=0;
	}
	Complex(int r, int i)   //构造函数重载
	{
		real = r;
		image = i;
	}
	Complex operator + (Complex &c1);     //声明重载运算符的函数
	
};
Complex Complex::operator + (Complex &c1)    //定义运算符重载函数
{
	Complex c;
	c.real= real + c1.real;
	c.image = image + c1.image;
	return c;
}

int main()
{
	Complex c1(2,5),c2(4,6),c3;
	c3=c1+c2;    
	cout<<"c1+c2="<<c3.real<<"+"<<c3.image<<"i"<<endl;
	return 0;
}

运算符重载函数既可以作为成员函数也可以作为友元函数
上面那段代码是将运算符重载函数作为成员函数,下面则是作为友元函数

# include<iostream.h>
class Complex
{
public:
	int real;
	int image;
	Complex()       //构造函数
	{
		real=0;
		image=0;
	}
	Complex(int r, int i)   //构造函数重载
	{
		real = r;
		image = i;
	}
	friend Complex operator + (Complex &c1,Complex &c2);     //声明重载运算符的函数
	
};
Complex operator + (Complex &c1,Complex &c2)   //定义运算符重载函数
{
	Complex c;
	c.real= c1.real + c2.real;
	c.image = c1.image + c2.image;
	return c;
}

int main()
{
	Complex c1(2,5),c2(4,6),c3;
	c3=c1+c2;    
	cout<<"c1+c2="<<c3.real<<"+"<<c3.image<<"i"<<endl;
	return 0;
}

再看一段代码

# include<iostream.h>
class Complex
{
public:
	int real;
	int image;
	Complex()       //构造函数
	{
		real=0;
		image=0;
	}
	Complex(int r, int i)   //构造函数重载
	{
		real = r;
		image = i;
	}
	friend Complex operator + (Complex &c1,Complex &c2);     //声明重载运算符的函数,作为友元函数
	Complex operator + (int &c1);     //声明重载运算符的函数,作为成员函数
	
	
};
Complex operator + (Complex &c1,Complex &c2)   //友元函数的定义
{
	Complex c;
	c.real= c1.real + c2.real;
	c.image = c1.image + c2.image;
	return c;
}
Complex Complex::operator + (int &i)    //成员函数的定义
{
	Complex c;
	c.real= real + i;
	c.image = image ;
	return c;
}

int main()
{
	Complex c1(2,5),c2(4,6),c3,c4;
	int i=5;

	c3=c1+c2;    
	cout<<"c1+c2="<<c3.real<<"+"<<c3.image<<"i"<<endl;
	c4=c1+i;
	cout<<"c1+c2="<<c4.real<<"+"<<c4.image<<"i"<<endl;
	return 0;
}

上面这段代码对运算符“+”重载了两次,一次作为友元函数重载,一次作为成员函数重载。实现了Complex类与Complex类、Complex类和C++标准类型(int型)数据的相加

**重载时作为友元函数和成员函数的区别:**如果重载为友元函数,那么必须要在函数的形参列表中列出所有的操作数,如Complex operator + (Complex &c1,Complex &c2),而如果重载为成员函数,如Complex operator + (int &c1);Complex Complex::operator + (int &i)虽然可以在函数的形参列表中省略一个参数,但是在运算符的左侧必须是Complex类的对象

即,如果重载为成员函数 Complex operator + (int &c1):
c2=c1+i;      //正确
c2=i+c1;      //错误,+左侧须为Complex类对象

如果重载为成员函数,但是在参数列表中不省略参数呢?

# include<iostream.h>
class Complex
{
public:
	int real;
	int image;
	Complex()       //构造函数
	{
		real=0;
		image=0;
	}
	Complex(int r, int i)   //构造函数重载
	{
		real = r;
		image = i;
	}
//	friend Complex operator + (Complex &c1,Complex &c2);     //声明重载运算符的函数,作为友元函数
	Complex operator + (int &i, Complex &c2);     //声明重载运算符的函数,作为成员函数
	
	
};

Complex Complex::operator + (int &i, Complex &c2)    //成员函数的定义
{
	Complex c;
	c.real= c2.real + i;
	c.image = image ;
	return c;
}

int main()
{
	Complex c1(2,5),c2(4,6),c3,c4;
	int i=5;

//	c3=c1+c2;    
//	cout<<"c1+c2="<<c3.real<<"+"<<c3.image<<"i"<<endl;
	c4=c1+i;
	cout<<"i+c1="<<c4.real<<"+"<<c4.image<<"i"<<endl;
	return 0;
}

运行结果:
--------------------Configuration: project2 - Win32 Debug--------------------
Compiling...
project2.cpp
E:\CPP-learning\project2.cpp(18) : error C2804: binary 'operator +' has too many parameters
E:\CPP-learning\project2.cpp(38) : error C2676: binary '+' : 'class Complex' does not define this operator or a conversion to a type acceptable to the predefined operator
执行 cl.exe 时出错.

project2.exe - 1 error(s), 0 warning(s)

原因很简单:如果按照上面代码中的运算符重载方式,显然成员函数并没有访问类的数据成员,而是仅仅访问了外部变量,这与成员函数的作用相矛盾。因此编译错误,显示重载函数的形参列表中有太多的参数。

另外,究竟什么时候运算符应该重载为友元函数,什么时候重载为成员函数也是有规定的。

再看一个例子,重载“>”,使得通过">"可以比较两个字符串的大小。

先定义一个String类

# include<iostream>
using namespace std;
class String
{
public:
	String()
	{
		p=NULL;
	}
	String(char *str);
	void display();
private:
	char *p;

};
String::String(char *str)
	{
		p = str;
	}
void String::display()
{
	cout<<p<<endl;
}

int main()
{
	String str1("Hello"), str2("Book");
	str1.display();
	str2.display();
	return 0;
}

加上运算符重载的代码

# include<iostream>
# include <string.h>
using namespace std;
class String
{
public:
	String()
	{
		p=NULL;
	}
	String(char *str);
	void display();
	friend bool operator > (String &str1, String &str2);
	
	
private:
	char *p;

};
	 bool operator > (String &str1, String &str2)
	{
		if (strcmp(str1.p,str2.p)>0)
			return true;
		else return false;
	}


String::String(char *str)
	{
		p = str;
	}
void String::display()
{
	cout<<p<<endl;
}
int main()
{
	char *p1 ="Hello", *p2 ="Book";
	String str1(p1), str2(p2);
	str1.display();
	str2.display();
	int b;
	b= (str1 > str2)?1:0;
	cout<<b<<endl;
	return 0;
}

运行结果:
[Running] cd "e:\CPP-learning\" && g++ project2.cpp -o project2 && "e:\CPP-learning\"project2
project2.cpp: In function 'int main()':
project2.cpp:38:12: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
  char *p1 ="Hello", *p2 ="Book";
            ^~~~~~~
project2.cpp:38:26: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
  char *p1 ="Hello", *p2 ="Book";
                          ^~~~~~
Hello
Book
1

注意:上面的代码在GCC编译器上运行是可以的,但是在VC++6.0上运行的话:

--------------------Configuration: project2 - Win32 Debug--------------------
Compiling...
project2.cpp
E:\CPP-learning\project2.cpp(21) : error C2248: 'p' : cannot access private member declared in class 'String'
        E:\CPP-learning\project2.cpp(16) : see declaration of 'p'
E:\CPP-learning\project2.cpp(21) : error C2248: 'p' : cannot access private member declared in class 'String'
        E:\CPP-learning\project2.cpp(16) : see declaration of 'p'
E:\CPP-learning\project2.cpp(42) : error C2593: 'operator >' is ambiguous
执行 cl.exe 时出错.

project2.exe - 1 error(s), 0 warning(s)

得改成这样:

# include<iostream>
# include <string.h>
using namespace std;
class String
{
public:
	String()
	{
		p=NULL;
	}
	String(char *str);
	void display();
	friend bool operator > (String &str1, String &str2)
	{
		if (strcmp(str1.p,str2.p)>0)
			return true;
		else return false;
	}
	
private:
	char *p;

};
//	 bool operator > (String &str1, String &str2)
//	{
//		if (strcmp(str1.p,str2.p)>0)
//			return true;
//		else return false;
//	}


String::String(char *str)
	{
		p = str;
	}
void String::display()
{
	cout<<p<<endl;
}
int main()
{
	char *p1 ="Hello", *p2 ="Book";
	String str1(p1), str2(p2);
	str1.display();
	str2.display();
	int b;
	b= (str1 > str2)?1:0;
	cout<<b<<endl;
	return 0;
}

运行结果:
Hello
Book
1
Press any key to continue

重载++ 先自增1使用自增1后的变量值

# include <iostream>
using namespace std;
class Time
{
    public:
        Time()
        {
            min=0;
            sec=0;
        }
        Time(int m, int s):min(m),sec(s){}
        Time operator ++(); //重载++
        void display()
            {
                cout<<min<<":"<<sec<<endl;
            }
    private:
        int min;
        int sec;
};
Time Time::operator ++()
{
    if (++sec>=60)
    {  sec-=60;
        min++;
    }
      
return *this;
}

int main()
{
Time t1(12,35);
++t1;
t1.display();
    return 0;
}

重载++,先使用变量值,再后自增

# include <iostream>
using namespace std;
class Time
{
    public:
        Time()
        {
            min=0;
            sec=0;
        }
        Time(int m, int s):min(m),sec(s){}
        Time operator ++(int); //重载++
        void display()
            {
                cout<<min<<":"<<sec<<endl;
            }
    private:
        int min;
        int sec;
};
Time Time::operator ++(int)
{
    Time temp = *this;
    if (++sec>=60)
    {  sec-=60;
        min++;
    }
      
return temp;
}

int main()
{
Time t1(12,35), t2;
t2=t1++;

t1.display();
t2.display();
    return 0;
}

重载<<

# include <iostream>
using namespace std;

class Complex
{
public:
	Complex()
	{
	real=0;
	image=0;
	}
	Complex(int r, int i): real(r), image(i){}
	friend ostream& operator << (ostream &, Complex &);

private:
	int real;
	int image;
};
ostream& operator << (ostream & cout, Complex & c1)
{
	
	cout<<c1.real<<"+"<<c1.image<<"i"<<endl;
	return cout;   
}

int main()
{
	Complex c1(3,5),c2(4,5);
	cout<<c1<<c2<<endl;
return 0;
}

**注意:**在重载友元函数的定义中,必须要返回ostream类的形参对象名(此处为cout),不能自己再定义一个ostream cout1 然后 return cout

重载 >>运算符, 方法与重载<<运算符类似

参考文献:《C++程序设计》 谭浩强

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值