C++运算符重载时参数什么时候要加&?什么时候要加c const 参数?

运算符重载就是赋予已有的运算符多重含义。通过重新定义运算符,使它能够用于特定类的对象执行特定的功能,这便增强了C++语言的扩充能力。1.运算符重载的作用:运算符重载允许C/C++的运算符在用户定义类型(类)上拥有一个用户定义的意义。重载的运算符是函数调用的语法修饰:classFred{public://...};#if0//没有算符重载:Fredadd(Fred,Fred);Fredmul(Fred,Fred);Fredf(Freda,Fredb,Fredc){returnadd(add(mul(a,b),mul(b,c)),mul(c,a));//哈哈,多可笑...}#else//有算符重载:Fredoperator+(Fred,Fred);Fredoperator*(Fred,Fred);Fredf(Freda,Fredb,Fredc){returna*b+b*c+c*a;}#endif2.可以用作重载的运算符:算术运算符:+,-,*,/,%,++,--;位操作运算符:&,|,~,^,<<,>>逻辑运算符:!,&&,||;比较运算符:<,>,>=,<=,==,!=;赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。下列运算符不允许重载:.,.*,::,?:3.运算符重载后,优先级和结合性:用户重载新定义运算符,不改变原运算符的优先级和结合性。这就是说,对运算符重载不改变运算符的优先级和结合性,并且运算符重载后,也不改变运算符的语法结构,即单目运算符只能重载为单目运算符,双目运算符只能重载双目运算符。4.编译程序如何选用哪一个运算符函数:运算符重载实际是一个函数,所以运算符的重载实际上是函数的重载。编译程序对运算符重载的选择,遵循着函数重载的选择原则。当遇到不很明显的运算时,编译程序将去寻找参数相匹配的运算符函数。5.重载运算符有哪些限制:(1)不可臆造新的运算符。必须把重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中。(2)重载运算符坚持4个“不能改变”。·不能改变运算符操作数的个数;·不能改变运算符原有的优先级;·不能改变运算符原有的结合性;·不能改变运算符原有的语法结构。6.运算符重载时必须遵循哪些原则:运算符重载可以使程序更加简洁,使表达式更加直观,增加可读性。但是,运算符重载使用不宜过多,否则会带来一定的麻烦。(1)重载运算符含义必须清楚。(2)重载运算符不能有二义性。运算符重载函数的两种形式运算符重载的函数一般地采用如下两种形式:成员函数形式和友元函数形式。这两种形式都可访问类中的私有成员。1.重载为类的成员函数这里先举一个关于给复数运算重载复数的四则运算符的例子。复数由实部和虚部构造,可以定义一个复数类,然后再在类中重载复数四则运算的运算符。先看以下源代码:#include<iostream.h>classcomplex{public:complex(){real=imag=0;}complex(doubler,doublei){real=r,imag=i;}complexoperator+(constcomplex&c);complexoperator-(constcomplex&c);complexoperator*(constcomplex&c);complexoperator/(constcomplex&c);friendvoidprint(constcomplex&c);private:doublereal,};inlinecomplexcomplex::operator+(constcomplex&c){returncomplex(real+c.real,imag+c.imag);}inlinecomplexcomplex::operator-(constcomplex&c){returncomplex(real-c.real,imag-c.imag);}inlinecomplexcomplex::operator*(constcomplex&c){returncomplex(real*c.real-imag*c.imag,real*c.imag+imag*c.real);}inlinecomplexcomplex::operator/(constcomplex&c){returncomplex((real*c.real+imag+c.imag)/(c.real*c.real+c.imag*c.imag),(imag*c.real-real*c.imag)/(c.real*c.real+c.imag*c.imag));}voidprint(constcomplex&c){if(c.imag<0)cout<<c.real<<c.imag<<'i';elsecout<<c.real<<'+'<<c.imag<<'i';}voidmain(){complexc1(2.0,3.0),c2(4.0,-2.0),c3;c3=c1+c2;cout<<"\nc1+c2=";print(c3);c3=c1-c2;cout<<"\nc1-c2=";print(c3);c3=c1*c2;cout<<"\nc1*c2=";print(c3);c3=c1/c2;cout<<"\nc1/c2=";print(c3);c3=(c1+c2)*(c1-c2)*c2/c1;cout<<"\n(c1+c2)*(c1-c2)*c2/c1=";print(c3);cout<<}该程序的运行结果为:c1+c2=6+1ic1-c2=-2+5ic1*c2=14+8ic1/c2=0.45+0.8i(c1+c2)*(c1-c2)*c2/c1=9.8i在程序中,类complex定义了4个成员函数作为运算符重载函数。将运算符重载函数说明为类的成员函数格式如下:<类名>operator<运算符>(<参数表>)其中,operator是定义运算符重载函数的关键字。程序中出现的表达式:c1+c2编译程序将给解释为:c1.operator+(c2)其中,c1和c2是complex类的对象。operator+()是运算+的重载函数。该运算符重载函数仅有一个参数c2。可见,当重载为成员函数时,双目运算符仅有一个参数。对单目运算符,重载为成员函数时,不能再显式说明参数。重载为成员函数时,总时隐含了一个参数,该参数是this指针。this指针是指向调用该成员函数对象的指针。2.重载为友元函数:运算符重载函数还可以为友元函数。当重载友元函数时,将没有隐含的参数this指针。这样,对双目运算符,友元函数有2个参数,对单目运算符,友元函数有一个参数。但是,有些运行符不能重载为友元函数,它们是:=,(),[]和->。重载为友元函数的运算符重载函数的定义格式如下:friend<类型说明符>operator<运算符>(<参数表>){……}下面用友元函数代码成员函数,重载编写上述的例子,程序如下:#include<iostream.h>classcomplex{public:complex(){real=imag=0;}complex(doubler,doublei){real=r,imag=i;}friendcomplexoperator+(constcomplex&c1,constcomplex&c2);friendcomplexoperator-(constcomplex&c1,constcomplex&c2);friendcomplexoperator*(constcomplex&c1,constcomplex&c2);friendcomplexoperator/(constcomplex&c1,constcomplex&c2);friendvoidprint(constcomplex&c);private:doublereal,};complexoperator+(constcomplex&c1,constcomplex&c2){returncomplex(c1.real+c2.real,c1.imag+c2.imag);}complexoperator-(constcomplex&c1,constcomplex&c2){returncomplex(c1.real-c2.real,c1.imag-c2.imag);}complexoperator*(constcomplex&c1,constcomplex&c2){returncomplex(c1.real*c2.real-c1.imag*c2.imag,c1.real*c2.imag+c1.imag*c2.real);}complexoperator/(constcomplex&c1,constcomplex&c2){returncomplex((c1.real*c2.real+c1.imag+c2.imag)/(c2.real*c2.real+c2.imag*c2.imag),(c1.imag*c2.real-c1.real*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag));}voidprint(constcomplex&c){if(c.imag<0)cout<<c.real<<c.imag<<'i';elsecout<<c.real<<'+'<<c.imag<<'i';}voidmain(){complexc1(2.0,3.0),c2(4.0,-2.0),c3;c3=c1+c2;cout<<"\nc1+c2=";print(c3);c3=c1-c2;cout<<"\nc1-c2=";print(c3);c3=c1*c2;cout<<"\nc1*c2=";print(c3);c3=c1/c2;cout<<"\nc1/c2=";print(c3);c3=(c1+c2)*(c1-c2)*c2/c1;cout<<"\n(c1+c2)*(c1-c2)*c2/c1=";print(c3);cout<<}该程序的运行结果与上例相同。前面已讲过,对又目运算符,重载为成员函数时,仅一个参数,另一个被隐含;重载为友元函数时,有两个参数,没有隐含参数。因此,程序中出现的c1+c2编译程序解释为:operator+(c1,c2)调用如下函数,进行求值,complexoperator+(constcoplex&c1,constcomplex&c2)3.两种重载形式的比较一般说来,单目运算符最好被重载为成员;对双目运算符最好被重载为友元函数,双目运算符重载为友元函数比重载为成员函数更方便此,但是,有的双目运算符还是重载为成员函数为好,例如,赋值运算符。因为,它如果被重载为友元函数,将会出现与赋值语义不一致的地方。其他运算符的重载举例1).下标运算符重载由于C语言的数组中并没有保存其大小,因此,不能对数组元素进行存取范围的检查,无法保证给数组动态赋值不会越界。利用C++的类可以定义一种更安全、功能强的数组类型。为此,为该类定义重载运算符[]。下面一个例子:#include<iostream.h>classCharArray{public:CharArray(intl){Length=l;Buff=newchar[Length];}~CharArray(){deleteB}intGetLength(){returnL}char&operator[](inti);private:intLchar*B};char&CharArray::operator[](inti){staticcharch=0;if(i<Length&&i>=0)returnBuff[i];else{cout<<"\nIndexoutofrange.";}}voidmain(){CharArraystring1(6);char*string2="string";for(cnt=0;cnt<8;cnt++)string1[cnt]=string2[cnt];cout<<"\n";for(cnt=0;cnt<8;cnt++)cout<<string1[cnt];cout<<"\n";cout<<string1.GetLength()<<}该数组类的优点如下:(1)其大小不一定是一个常量。(2)运行时动态指定大小可以不用运算符new和delete。(3)当使用该类数组作函数参数时,不心分别传递数组变量本身及其大小,因为该对象中已经保存大小。在重载下标运算符函数时应该注意:(1)该函数只能带一个参数,不可带多个参数。(2)不得重载为友元函数,必须是非static类的成员函数。2).重载增1减1运算符.增1减1运算符是单目运算符。它们又有前缀和后缀运算两种。为了区分这两种运算,将后缀运算视为又目运算符。表达式obj++或obj--被看作为:obj++0或obj--0下面举一例子说明重载增1减1运算符的应用。#include<iostream.h>classcounter{public:counter(){v=0;}counteroperator++();counteroperator++(int);voidprint(){cout<<v<<}private:};countercounter::operator++(){v++;return*}countercounter::operator++(int){t.v=v++;}voidmain(){for(inti=0;i<8;i++)c++;c.print();for(i=0;i<8;i++)++c;c.print();}3).重载函数调用运算符可以将函数调用运算符()看成是下标运算[]的扩展。函数调用运算符可以带0个至多个参数。下面通过一个实例来熟悉函数调用运算符的重载。#include<iostream.h>classF{public:doubleoperator()(doublex,doubley)};doubleF::operator()(doublex,doubley)const{return(x+5)*y;}voidmain(){Ff;cout<<f(1.5,2.2)<<}希望能对你有所帮助~
相关问题相关搜索
随时随地有问必答![C++]普通类运算符重载没问题,但是要用到set(stl库的东西)出错了,加了个const就编译通过了,为什么?
(附张图片)&img src=&/512d3f26fb7bac40c95e05_b.jpg& data-rawwidth=&292& data-rawheight=&187& class=&content_image& width=&292&&&br&以上代码编译通过,&b&但是&/b&&br&把圈住的cons去掉,那么编译会出错&br&如果不用到stl库的话,编译一切通过,但是加入set就说有4个错误&br&C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\stl_function.h: In member function&br&`bool std::less&_Tp&::operator()(const _Tp&, const _Tp&) const [with _Tp =&br&Re]':&br&C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\stl_tree.h:1042: instantiated from `std::pair&std::_Rb_tree_iterator&_Val, _Val&, _Val*&, bool& std::_Rb_tree&_Key, _Val, _KeyOfValue, _Compare, _Alloc&::insert_unique(const _Val&) [with _Key = Re, _Val = Re, _KeyOfValue = std::_Identity&Re&, _Compare = std::less&Re&, _Alloc = std::allocator&Re&]'&br&C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\stl_set.h:155: instantiated from `std::pair&typename std::_Rb_tree&_Key, _Key, std::_Identity&_Key&, _Compare, _Alloc&::const_iterator, bool& std::set&_Key, _Compare, _Alloc&::insert(const _Key&) [with _Key = Re, _Compare = std::less&Re&, _Alloc = std::allocator&Re&]'&br&memory.cpp:79: instantiated from here&br&C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\stl_function.h:197: error: passing&br&`const Re' as `this' argument of `bool Re::operator&(const Re&)' discards&br&qualifiersset是这样定义的:&br&set&Re&S&br&仅仅进行了插入操作:&br&Re InsO&br&Set.insert(InsObj);&br&我用的是很不常见的MingwStudio&br&&br&顺便吐槽一下知乎的格式。。简略阅读的时候竟然没有换行!
(附张图片)以上代码编译通过,但是把圈住的cons去掉,那么编译会出错如果不用到stl库的话,编译一切通过,但是加入set就说有4个错误C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\stl_function.h: In member function`bool std::less&_Tp&::operator()(const _Tp&, const _Tp&) const [with _Tp =Re]':C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\stl_tree.h:1042: instantiated from `std::pair&std::_Rb_tree_iterator&_Val, _Val&, _Val*&, bool& std::_Rb_tree&_Key, _Val, _KeyOfValue, _Compare, _Alloc&::insert_unique(const _Val&) [with _Key = Re, _Val = Re, _KeyOfValue = std::_Identity&Re&, _Compare = std::less&Re&, _Alloc = std::allocator&Re&]'…
按投票排序
跟到 insert(...) 里你可以看到它调用了参数的 & 操作符,而它接收参数又是 const 类型,所以这个 & 必须是 const。
你可以把操作符重载写在类外面,lhs和rhs都写成const类型的,这样只需要定义一个函数反正operator&的行为不会改变参数的值
set取出排序树中的结点N1,N2,N3来和你的insObj比较,像这样, if(N1&insObj),而N1,N2,N3都是const的。而你重载的operator& 的左操作数却是非const。
insert(const _Key&)
已有帐号?
无法登录?
社交帐号登录求助:c++C++ 运算符重载 的参数问题_百度知道
求助:c++C++ 运算符重载 的参数问题
举个例子解释一下
出例子的时候麻烦在重要语句上讲解一下......
提问者采纳
complex() { real=imag=0:
friend <类型说明符> operator <运算符>(<参数表>)
{……}下面用友元函数代码成员函数;},->,对双目运算符。它们又有前缀和后缀运算两种:operator &#47,有的双目运算符还是重载为成员函数为好, imag = i。 其他运算符的重载举例1); (c;}counter counter, const complex &c2):运算符重载实际是一个函数,不可带多个参数, const complex &c2){return complex((c1;<<c,new, double y) const{return (x+5)*y.&print(c3);.imag + c2.real * c2.imag<0)cout<<c; c2;char * Buff。函数调用运算符可以带0个至多个参数,%=.imag * c.real * c2,因为该对象中已经保存大小,遵循着函数重载的选择原则, imag.h>class F{print(c3);, c2(4:operator ++(int){counter t,对单目运算符,<<=:#include <iostream。当重载友元函数时. 重载为类的成员函数这里先举一个关于给复数运算重载复数的四则运算符的例子,c));n&cout<<& (c2;friendvoid print(const complex &c), double i){real =complex operator +(const complex &c1.real * c2;print(c3):(1) 该函数只能带一个参数:算术运算符:operator -(const complex &c){return complex(real - c, c1. 重载增1减1运算符。 运算符重载函数的两种形式运算符重载的函数一般地采用如下两种形式.imag<<&#39,|.imag):<;&#92.}, c2(4;c3 = c1 &#47。·不能改变运算符操作数的个数;Fred f(Fred a.print()。(2) 不得重载为友元函数;cout<<&quot。为了区分这两种运算:;位操作运算符,然后再在类中重载复数四则运算的运算符,类complex定义了4个成员函数作为运算符重载函数;n(c1+c2)*(c1-c2)*c2&#47,多可笑;\Buff = new char[Length];complex operator *(const complex &c);对双目运算符最好被重载为友元函数.real * i<8.imag):, Fred); cnt<8;c2=&quot.real - c1, const complex &c2){return complex(c1.real), c3。为此.2)<<endl. 编译程序如何选用哪一个运算符函数:
c1:int Length,编译程序将去寻找参数相匹配的运算符函数;elsecout<<c,delete[];nc1*c2=&quot:;C++的运算符在用户定义类型(类)上拥有一个用户定义的意义;c3 = c1 &#47,双目运算符仅有一个参数.imag),使表达式更加直观,不改变原运算符的优先级和结合性。4;friend void print(const complex &c);.imag - c2;,delete,有些运行符不能重载为友元函数。#include <print(c3).}.imag * c2:.}#else/\cout<<&quot.imag<<'<<c;c1;cout<<&&#47. (c2,a)),重载为成员函数时, mul(b,(c1.imag).; cnt++)string1[cnt] = string2[cnt];cout<<c3 = c1 + c2;print(c3)。利用C++的类可以定义一种更安全, double y) const,双目运算符只能重载双目运算符,该参数是this指针.h>class counter{i&#39。表达式
obj++或obj--被看作为,当重载为成员函数时:用户重载新定义运算符;c,将会出现与赋值语义不一致的地方;;cout<<&quot,单目运算符最好被重载为成员;t,->*;c2=0;&#92.imag * c,将后缀运算视为又目运算符,友元函数有2个参数。这两种形式都可访问类中的私有成员, Fred c){return a*b + b*c + c*a; i<8:,使它能够用于特定类的对象执行特定的功能,-=.imag<<',~;(const complex &c1,;&#92, const complex &c2){return complex(c1;n(c1+c2)*(c1-c2)*c2/;print(c3), const complex &c2),为该类定义重载运算符[],*=,[]和->, Fred b.real<<&#39.imag<<&#39?,--,^,并且运算符重载后, c3;c3 = c1 - c2,>=.real * c2,运算符重载使用不宜过多. 重载函数调用运算符可以将函数调用运算符()看成是下标运算[]的扩展,但是;,有两个参数:counter() { v=0::运算符重载函数还可以为友元函数..real, imag + c,;&#47,>>逻辑运算符。先看以下源代码。这样:operator ++(){v++;nc1&#47,*:;\print(c3);char & CharArray,/c3 = (c1+c2) * (c1-c2) * c2&#47.print();friend complex operator -(const complex &c1.imag) /·不能改变运算符原有的结合性,否则会带来一定的麻烦.0).real<<c,++.real + c1;}inline complex complex,!=;·不能改变运算符原有的语法结构:c1+c2=6+1ic1-c2=-2+5ic1*c2=14+8ic1/char * string2 = &quot, 3.;} 该数组类的优点如下;return ch:double operator ()(double x,增加可读性.imag)。(2) 重载运算符坚持4个“不能改变”;return t。下面一个例子;}}void main(){int cnt, Fred c){return add(add(mul(a;cout<<&quot:
obj++0或obj--0下面举一例子说明重载增1减1运算符的应用, const complex &c2);c3 = c1 * c2;cout<<& }nc1*c2=&quot,&&; i++)c++:operator ()(double x.*,友元函数有一个参数:&,无法保证给数组动态赋值不会越界;;}~CharArray() { delete B赋值运算符;friend complex operator *(const complex &c1。1,<<,^=;elsecout<<c,双目运算符重载为友元函数比重载为成员函数更方便此;print(c3); }complex(inline complex complex。重载为成员函数时;for(i=0;}complex operator -(const complex &c1;c1=&quot,总时隐含了一个参数,例如:operator +(const complex &c){return complex(real + c:class Fred{return *this,%.8i(c1+c2)*(c1-c2)*c2&#47, Fred)。在重载下标运算符函数时应该注意;double F;}complex operator +(const complex &c),进行求值.h>class complex{public, imag = i,不能对数组元素进行存取范围的检查, real * 哈哈, mul(c, imag - c. 两种重载形式的比较一般说来:#include <iostream:string&nc1+c2=&quot。6.imag + imag *i&#39.real)。但是;:nc1+c2=&quot,没有隐含参数:[],它如果被重载为友元函数,另一个被隐含;Fred f(Fred a.imag + c1。对单目运算符;&#92,可以定义一个复数类,>:double real:
operator+(c1.imag,赋值运算符.real - imag * c,.0;for(int i=0;,(), c2)调用如下函数.下标运算符重载由于C语言的数组中并没有保存其大小,也不改变运算符的语法结构。下面通过一个实例来熟悉函数调用运算符的重载,<=.imag) &#47:complex() { real=imag=0。(3) 当使用该类数组作函数参数时;}complex operator *(const complex &c1;c3 = (c1+c2) * (c1-c2) * c2&#47::成员函数形式和友元函数形式.imag * c2;.real + c2.real - real *c1:/#if 0&#47,operator是定义运算符重载函数的关键字;&#92:operator [](int i){static char ch = 0;cout<<&quot. 可以用作重载的运算符;};complex operator &#47,&#47.61538+25.real +print(c3).real + c2!;.imag * c2;cout<<&}void main(){complex c1(2.print(c3); }char & operator [](int i).h>class CharArray{public.0).real + c2; c2:(1) 其大小不一定是一个常量.5.0),-,(逗号运算符); cnt++)cout<<string1[cnt];complex operator -(const complex &c).real<<&#39,优先级和结合性.0;}void main(){ }counter operator ++(), c1:=.imag));+&#39,对运算符重载不改变运算符的优先级和结合性。因为;·不能改变运算符原有的优先级。程序中出现的表达式; }complex(double r。this指针是指向调用该成员函数对象的指针.real + 没有算符重载, c1;比较运算符。可见;for(cnt=0,;cout<<&i&#39。#include <iostream:;。因此. 运算符重载后.imag * c2:运算符重载可以使程序更加简洁.v = v++,重载为成员函数时。前面已讲过:.real.GetLength()<<endl, -2,
complex operator +(const coplex &c1。下列运算符不允许重载;else{cout<<&nIndex out of range。编译程序对运算符重载的选择; i++)++c; 有算符重载.real - c1.imag * c2:,即单目运算符只能重载为单目运算符;c3 = c1 * c2;CharArray string1(6)。但是.增1减1运算符是单目运算符。 2)。重载为友元函数的运算符重载函数的定义格式如下;&#47。这就是说,|=;c:=,&=, const complex &c2){return complex(c1:,程序如下.,因此;}.imag + c2;n&quot, -2;}。operator+()是运算+的重载函数.h>class complex{c2=&quot:(1) 不可臆造新的运算符. 重载为友元函数,重载编写上述的例子.imag) &#47,不心分别传递数组变量本身及其大小.imag);friend complex operator /counter counter, imag,仅一个参数;c1=9.45+0;.imag)); 。1.real * c2,>>=,c1和c2是complex类的对象, 2;nc1-c2=&quot。当遇到不很明显的运算时:#include <;private, const complex &c2). 重载运算符有哪些限制;\i'private。该运算符重载函数仅有一个参数c2;}void print(const complex &c){if(c。(2) 运行时动态指定大小可以不用运算符new和delete, double i){real = r.0).real<<c;cout<<&quot,+=;}void main(){complex c1(2。必须把重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中:Fred add(Fred.real + imag + c,(imag * (c,它们是:operator *(const complex &c){return complex(real *cout<<string1.operator+(c2)其中;}complex operator /c3 = c1 - c2;(const complex &c){return complex((real *nc1-c2=&counter operator ++(int )。复数由实部和虚部构造.imag<0)cout<<c.2308i 在程序中;}#endif 2; }int GetLength() { return L/(const complex &c);=。(2) 重载运算符不能有二义性:3.0;}infor(cnt=0; /cout<<f(1:+;nc1/(const complex &c1; cnt<8.real - c2。重载的运算符是函数调用的语法修饰;c3 = c1 + c2. 运算符重载的作用;;}void main(){F&#92,(). 运算符重载时必须遵循哪些原则,将没有隐含的参数this指针.imag) /重载为友元函数时;}friend complex operator +(const complex &c1, const complex &c2) 3;。将运算符重载函数说明为类的成员函数格式如下;;\+&#39, Fred);void print() { cout<<v<<&#92.real * c2:运算符重载允许C/c1=&quot。2:
c1+c2编译程序将给解释为。5,对又目运算符;} 3).0,程序中出现的 c1+c2编译程序解释为;Fred mul(Fred.,必须是非static类的成员函数;Fred operator* (Fred:Fred operator+ (F} 该程序的运行结果为,不能再显式说明参数, Fred).real *其他运算符运算符重载就是赋予已有的运算符多重含义, Fred b,所以运算符的重载实际上是函数的重载。通过重新定义运算符,==;}void print(const complex &c){if(c;} 该程序的运行结果与上例相同, 3;if(i<Length&&i>=0)return Buff[i],||,这便增强了C++语言的扩充能力。(1) 重载运算符含义必须清楚;cout<<endl、功能强的数组类型;cout<<&}in&#92:<类名> operator <运算符>(<参数表>)其中:CharArray(int l){Length = l,b),new[]
提问者评价
其他类似问题
为您推荐:
其他1条回答
return this,Int&Idata*=x;n=n+2;&#47例如现有类Int:;/}例:Int n(10);n=20以上实际重载加法为乘法:operator+(int x){this-&gt
运算符重载的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁运算符重载就是赋予已有的运算符多重含义。通过重新定义运算符,使它能够用于特定类的对象执行特定的功能,这便增强了C++语言的扩充能力。1.运算符重载的作用:运算符重载允许C/C++的运算符在用户定义类型(类)上拥有一个用户定义的意义。重载的运算符是函数调用的语法修饰:classFred{public://...};#if0//没有算符重载:Fredadd(Fred,Fred);Fredmul(Fred,Fred);Fredf(Freda,Fredb,Fredc){returnadd(add(mul(a,b),mul(b,c)),mul(c,a));//哈哈,多可笑...}#else//有算符重载:Fredoperator+(Fred,Fred);Fredoperator*(Fred,Fred);Fredf(Freda,Fredb,Fredc){returna*b+b*c+c*a;}#endif2.可以用作重载的运算符:算术运算符:+,-,*,/,%,++,--;位操作运算符:&,|,~,^,<<,>>逻辑运算符:!,&&,||;比较运算符:<,>,>=,<=,==,!=;赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。下列运算符不允许重载:.,.*,::,?:3.运算符重载后,优先级和结合性:用户重载新定义运算符,不改变原运算符的优先级和结合性。这就是说,对运算符重载不改变运算符的优先级和结合性,并且运算符重载后,也不改变运算符的语法结构,即单目运算符只能重载为单目运算符,双目运算符只能重载双目运算符。4.编译程序如何选用哪一个运算符函数:运算符重载实际是一个函数,所以运算符的重载实际上是函数的重载。编译程序对运算符重载的选择,遵循着函数重载的选择原则。当遇到不很明显的运算时,编译程序将去寻找参数相匹配的运算符函数。5.重载运算符有哪些限制:(1)不可臆造新的运算符。必须把重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中。(2)重载运算符坚持4个“不能改变”。·不能改变运算符操作数的个数;·不能改变运算符原有的优先级;·不能改变运算符原有的结合性;·不能改变运算符原有的语法结构。6.运算符重载时必须遵循哪些原则:运算符重载可以使程序更加简洁,使表达式更加直观,增加可读性。但是,运算符重载使用不宜过多,否则会带来一定的麻烦。(1)重载运算符含义必须清楚。(2)重载运算符不能有二义性。运算符重载函数的两种形式运算符重载的函数一般地采用如下两种形式:成员函数形式和友元函数形式。这两种形式都可访问类中的私有成员。1.重载为类的成员函数这里先举一个关于给复数运算重载复数的四则运算符的例子。复数由实部和虚部构造,可以定义一个复数类,然后再在类中重载复数四则运算的运算符。先看以下源代码:#include<iostream.h>classcomplex{public:complex(){real=imag=0;}complex(doubler,doublei){real=r,imag=i;}complexoperator+(constcomplex&c);complexoperator-(constcomplex&c);complexoperator*(constcomplex&c);complexoperator/(constcomplex&c);friendvoidprint(constcomplex&c);private:doublereal,};inlinecomplexcomplex::operator+(constcomplex&c){returncomplex(real+c.real,imag+c.imag);}inlinecomplexcomplex::operator-(constcomplex&c){returncomplex(real-c.real,imag-c.imag);}inlinecomplexcomplex::operator*(constcomplex&c){returncomplex(real*c.real-imag*c.imag,real*c.imag+imag*c.real);}inlinecomplexcomplex::operator/(constcomplex&c){returncomplex((real*c.real+imag+c.imag)/(c.real*c.real+c.imag*c.imag),(imag*c.real-real*c.imag)/(c.real*c.real+c.imag*c.imag));}voidprint(constcomplex&c){if(c.imag<0)cout<<c.real<<c.imag<<'i';elsecout<<c.real<<'+'<<c.imag<<'i';}voidmain(){complexc1(2.0,3.0),c2(4.0,-2.0),c3;c3=c1+c2;cout<<"\nc1+c2=";print(c3);c3=c1-c2;cout<<"\nc1-c2=";print(c3);c3=c1*c2;cout<<"\nc1*c2=";print(c3);c3=c1/c2;cout<<"\nc1/c2=";print(c3);c3=(c1+c2)*(c1-c2)*c2/c1;cout<<"\n(c1+c2)*(c1-c2)*c2/c1=";print(c3);cout<<}该程序的运行结果为:c1+c2=6+1ic1-c2=-2+5ic1*c2=14+8ic1/c2=0.45+0.8i(c1+c2)*(c1-c2)*c2/c1=9.8i在程序中,类complex定义了4个成员函数作为运算符重载函数。将运算符重载函数说明为类的成员函数格式如下:<类名>operator<运算符>(<参数表>)其中,operator是定义运算符重载函数的关键字。程序中出现的表达式:c1+c2编译程序将给解释为:c1.operator+(c2)其中,c1和c2是complex类的对象。operator+()是运算+的重载函数。该运算符重载函数仅有一个参数c2。可见,当重载为成员函数时,双目运算符仅有一个参数。对单目运算符,重载为成员函数时,不能再显式说明参数。重载为成员函数时,总时隐含了一个参数,该参数是this指针。this指针是指向调用该成员函数对象的指针。2.重载为友元函数:运算符重载函数还可以为友元函数。当重载友元函数时,将没有隐含的参数this指针。这样,对双目运算符,友元函数有2个参数,对单目运算符,友元函数有一个参数。但是,有些运行符不能重载为友元函数,它们是:=,(),[]和->。重载为友元函数的运算符重载函数的定义格式如下:friend<类型说明符>operator<运算符>(<参数表>){……}下面用友元函数代码成员函数,重载编写上述的例子,程序如下:#include<iostream.h>classcomplex{public:complex(){real=imag=0;}complex(doubler,doublei){real=r,imag=i;}friendcomplexoperator+(constcomplex&c1,constcomplex&c2);friendcomplexoperator-(constcomplex&c1,constcomplex&c2);friendcomplexoperator*(constcomplex&c1,constcomplex&c2);friendcomplexoperator/(constcomplex&c1,constcomplex&c2);friendvoidprint(constcomplex&c);private:doublereal,};complexoperator+(constcomplex&c1,constcomplex&c2){returncomplex(c1.real+c2.real,c1.imag+c2.imag);}complexoperator-(constcomplex&c1,constcomplex&c2){returncomplex(c1.real-c2.real,c1.imag-c2.imag);}complexoperator*(constcomplex&c1,constcomplex&c2){returncomplex(c1.real*c2.real-c1.imag*c2.imag,c1.real*c2.imag+c1.imag*c2.real);}complexoperator/(constcomplex&c1,constcomplex&c2){returncomplex((c1.real*c2.real+c1.imag+c2.imag)/(c2.real*c2.real+c2.imag*c2.imag),(c1.imag*c2.real-c1.real*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag));}voidprint(constcomplex&c){if(c.imag<0)cout<<c.real<<c.imag<<'i';elsecout<<c.real<<'+'<<c.imag<<'i';}voidmain(){complexc1(2.0,3.0),c2(4.0,-2.0),c3;c3=c1+c2;cout<<"\nc1+c2=";print(c3);c3=c1-c2;cout<<"\nc1-c2=";print(c3);c3=c1*c2;cout<<"\nc1*c2=";print(c3);c3=c1/c2;cout<<"\nc1/c2=";print(c3);c3=(c1+c2)*(c1-c2)*c2/c1;cout<<"\n(c1+c2)*(c1-c2)*c2/c1=";print(c3);cout<<}该程序的运行结果与上例相同。前面已讲过,对又目运算符,重载为成员函数时,仅一个参数,另一个被隐含;重载为友元函数时,有两个参数,没有隐含参数。因此,程序中出现的c1+c2编译程序解释为:operator+(c1,c2)调用如下函数,进行求值,complexoperator+(constcoplex&c1,constcomplex&c2)3.两种重载形式的比较一般说来,单目运算符最好被重载为成员;对双目运算符最好被重载为友元函数,双目运算符重载为友元函数比重载为成员函数更方便此,但是,有的双目运算符还是重载为成员函数为好,例如,赋值运算符。因为,它如果被重载为友元函数,将会出现与赋值语义不一致的地方。其他运算符的重载举例1).下标运算符重载由于C语言的数组中并没有保存其大小,因此,不能对数组元素进行存取范围的检查,无法保证给数组动态赋值不会越界。利用C++的类可以定义一种更安全、功能强的数组类型。为此,为该类定义重载运算符[]。下面一个例子:#include<iostream.h>classCharArray{public:CharArray(intl){Length=l;Buff=newchar[Length];}~CharArray(){deleteB}intGetLength(){returnL}char&operator[](inti);private:intLchar*B};char&CharArray::operator[](inti){staticcharch=0;if(i<Length&&i>=0)returnBuff[i];else{cout<<"\nIndexoutofrange.";}}voidmain(){CharArraystring1(6);char*string2="string";for(cnt=0;cnt<8;cnt++)string1[cnt]=string2[cnt];cout<<"\n";for(cnt=0;cnt<8;cnt++)cout<<string1[cnt];cout<<"\n";cout<<string1.GetLength()<<}该数组类的优点如下:(1)其大小不一定是一个常量。(2)运行时动态指定大小可以不用运算符new和delete。(3)当使用该类数组作函数参数时,不心分别传递数组变量本身及其大小,因为该对象中已经保存大小。在重载下标运算符函数时应该注意:(1)该函数只能带一个参数,不可带多个参数。(2)不得重载为友元函数,必须是非static类的成员函数。2).重载增1减1运算符.增1减1运算符是单目运算符。它们又有前缀和后缀运算两种。为了区分这两种运算,将后缀运算视为又目运算符。表达式obj++或obj--被看作为:obj++0或obj--0下面举一例子说明重载增1减1运算符的应用。#include<iostream.h>classcounter{public:counter(){v=0;}counteroperator++();counteroperator++(int);voidprint(){cout<<v<<}private:};countercounter::operator++(){v++;return*}countercounter::operator++(int){t.v=v++;}voidmain(){for(inti=0;i<8;i++)c++;c.print();for(i=0;i<8;i++)++c;c.print();}3).重载函数调用运算符可以将函数调用运算符()看成是下标运算[]的扩展。函数调用运算符可以带0个至多个参数。下面通过一个实例来熟悉函数调用运算符的重载。#include<iostream.h>classF{public:doubleoperator()(doublex,doubley)};doubleF::operator()(doublex,doubley)const{return(x+5)*y;}voidmain(){Ff;cout<<f(1.5,2.2)<<}希望能对你有所帮助~
相关问题相关搜索
随时随地有问必答!

我要回帖

更多关于 运算符重载 参数 的文章

 

随机推荐