第五章 运算符重载 主要内容: ●运算符重载的基本概念:运算符重载函数的格式、可以重载的运算符,以及运算符重载 时遵循的基本原则 ●重载为类的成员函数:运算符重载为类的成员函数的一般格式、重载单目运算符和双目 运算符的特点,以及成员运算符函数的调用。 ● 重载为类的友元函数:运算符重载为类的友元函数的一般格式、重载双目运算符的特点, 以及有缘运算符函数的调用。 选择题 1下列运算符中,运算符在C十十中不能重载。 A?= B C new D&& 答案:A 注释:不能在C十十中重载的运算符:类属关系运算符“”、成员指针运算符“*”、作用域 运算符“:”、sizeof运算符和三目运算符“?:”。此外C十十中所有运算符都可以重载。 另外,=、()、、一>运算符不能重载为类的友元函数。 2友元运算符obj1>obj2被编译器解释为。 A operator>(objl,obj2)B>(objl,obj2) C obj2.operator>(obj1) D obj1.operator>(obj2) 答案:A 注释:重载为友元函数的运算符的调用形式 operator(,) 等价于 3下列关于C+十运算符函数的返回类型的描述中,错误的是 A可以是类类型 B可以是int类型C可以是void类型D可以是float类型 答案:C 注释:void类型数据不能参与运算。 4下面运算符重载的描述中,正确的是 A运算符重载可以改变运算符的操作数的个数 B运算符重载可以改变优先级 C运算符重载可以改变结合性 D运算符重载不可以改变语法结构 答案:D 注释:重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个 数及语法结构 5下面对C++运算符描述正确的是 A只有类成员运算符B只有友元运算符 C只有非成员和非友元运算符D上述都有 答案D 注释:运算符重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数,非成员 函数通常是友元函数。 填空题
第五章 运算符重载 主要内容: z 运算符重载的基本概念:运算符重载函数的格式、可以重载的运算符,以及运算符重载 时遵循的基本原则 z 重载为类的成员函数:运算符重载为类的成员函数的一般格式、重载单目运算符和双目 运算符的特点,以及成员运算符函数的调用。 z 重载为类的友元函数:运算符重载为类的友元函数的一般格式、重载双目运算符的特点, 以及有缘运算符函数的调用。 选择题 1 下列运算符中, 运算符在 C++中不能重载。 A ?= B [] C new D && 答案:A 注释:不能在 C++中重载的运算符:类属关系运算符“.”、成员指针运算符“.*”、作用域 运算符“::”、sizeof 运算符和三目运算符“?:”。此外 C++中所有运算符都可以重载。 另外,=、()、[]、->运算符不能重载为类的友元函数。 2 友元运算符 obj1>obj2 被编译器解释为 。 A operator>(obj1,obj2) B >(obj1,obj2) C obj2.operator>(obj1) D obj1.operator>(obj2) 答案:A 注释:重载为友元函数的运算符的调用形式 operator(,) 等价于 3 下列关于 C++运算符函数的返回类型的描述中,错误的是 。 A 可以是类类型 B 可以是 int 类型 C 可以是 void 类型 D 可以是 float 类型 答案:C 注释:void 类型数据不能参与运算。 4 下面运算符重载的描述中,正确的是 。 A 运算符重载可以改变运算符的操作数的个数 B 运算符重载可以改变优先级 C 运算符重载可以改变结合性 D 运算符重载不可以改变语法结构 答案:D 注释:重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个 数及语法结构 5 下面对 C++运算符描述正确的是 。 A 只有类成员运算符 B 只有友元运算符 C 只有非成员和非友元运算符 D 上述都有 答案 D 注释:运算符重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数,非成员 函数通常是友元函数。 填空题 1
1单目运算符作为类成员函数重载时没有形参:双目运算符作为类成员重载时需声明其右操 作数,作为友元函数重载时需要声明全部操作数 注释:当运算符重载为类的成员函数时,函数的参数个数比原来的操作数要少一个(后缀单 目运算符除外),这是因为成员函数用hs指针隐式地访问了类的一个对象,它充当了运算 符函数最左边的操作数 当运算符重载为类的友元函数时,由于没有隐含的hs指针,因此操作数的个数没有变化, 所有操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。 2为满足运算符+的可交换性,必须将其重载为友元函数。 3在类的对象上使用运算符,除了运算符=和&以外,其他的运算符都必须被重载。 4下列程序定义了一实部为real,虚部为imag的复数类complex,并在类中重载了复数的+、 一操作。请将下列程序补充完整。 Class Complex { public: Complex(double r=0.0,double I=0.0){real=r;imag=i) Complex operator +(Complex); friend Complex operator-(Complex.Complex); private: double real,imag: Complex Complex::operator+(Complex c) { return Complex(real+c.real.imag+C.imag ) } Complex_operator-(Complex c1,Complex c2) return Complex(c1.real-c2.real,c1.imag-c2.imag ) 写出程序的运行结果 include class Coord { public: Coord(int i=0,int j=0){x=I;y=j;} void Print(0 cout<-<"x=”<<x<<”,y=”<<endl;} friend Coord operator +(Coord op); private: int x,y; Coord operator +(Coord op) ++op.X; ++op.y, return op; 2
1 单目运算符作为类成员函数重载时没有形参;双目运算符作为类成员重载时需声明其右操 作数,作为友元函数重载时需要声明全部操作数 注释:当运算符重载为类的成员函数时,函数的参数个数比原来的操作数要少一个(后缀单 目运算符除外),这是因为成员函数用 this 指针隐式地访问了类的一个对象,它充当了运算 符函数最左边的操作数 当运算符重载为类的友元函数时,由于没有隐含的 this 指针,因此操作数的个数没有变化, 所有操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。 2 为满足运算符+的可交换性,必须将其重载为友元函数。 3 在类的对象上使用运算符,除了运算符=和&以外,其他的运算符都必须被重载。 4 下列程序定义了一实部为 real,虚部为 imag 的复数类 complex,并在类中重载了复数的+、 -操作。请将下列程序补充完整。 Class Complex { public: Complex(double r=0.0,double I=0.0){ real=r;imag=i; } Complex operator +(Complex); friend Complex operator-(Complex,Complex); private: double real,imag; }; Complex Complex:: operator+(Complex c) { return Complex( real+c.real,imag+C.imag ); } Complex operator-(Complex c1,Complex c2) { return Complex(c1.real-c2.real, c1.imag-c2.imag ); } 写出程序的运行结果 # include class Coord { public: Coord(int i=0,int j=0){x=I;y=j;} void Print(){cout<<”x=”<<x<<”,y=”<<endl;} friend Coord operator ++(Coord op); private: int x,y; }; Coord operator ++(Coord op) { ++op.x; ++op.y; return op; 2
void main() { Coord obj(1.2): obj.Print(); ++obj; obj.Print(); 答案: X=1,y=2 X=1,y=2 注释:利用成员函数重载运算符时,由于所有的成员函数都有一个this指针,this指针指向 该函数所属类对象,因此对私有数据的任何修改都将影响实际调用成员运算符函数的对象: 利用友元函数重载运算符时,由于友元函数没有this指针,所以不能引用ths指针所指向的 对象。 本例中函数时通过传值方法传递函数的,因此在operator-+函数中,任何内部的改变都不会 影响产生调用的操作数。为了解决这个问题,应采用引用参数传递操作数。也就是利用友元 函数重载时需要注意的问题。 程序设计 设计一个三角形类Triangle,包含三角形三条边长的私有数据成员,另有一个重载运算符 “十”,以实现求两个三角形对象的面积之和。 参考答案: 在Triangle类中设计一个友元函数operator+-(Triangle t1,Triangle t2),它重载运算符“+”, 返回t1和t2两个三角形的面积之和。 include include class Triangle { int x,y,Z; double area; public: Triangle (int i,int j,int k); { double s; x=i;y-j;z-k, s=(x+y+z)/2.0: area=sqrt(s*(s-x)*(s-y)*(s-z)); } void disparea() cout<<"Area=<<area<<ednl: 3
} void main() { Coord obj(1,2); obj.Print(); ++obj; obj.Print(); } 答案: x=1,y=2 x=1,y=2 注释:利用成员函数重载运算符时,由于所有的成员函数都有一个 this 指针,this 指针指向 该函数所属类对象,因此对私有数据的任何修改都将影响实际调用成员运算符函数的对象; 利用友元函数重载运算符时,由于友元函数没有 this 指针,所以不能引用 this 指针所指向的 对象。 本例中函数时通过传值方法传递函数的,因此在 operator++函数中,任何内部的改变都不会 影响产生调用的操作数。为了解决这个问题,应采用引用参数传递操作数。也就是利用友元 函数重载时需要注意的问题。 程序设计 设计一个三角形类 Triangle,包含三角形三条边长的私有数据成员,另有一个重载运算符 “+”,以实现求两个三角形对象的面积之和。 参考答案: 在 Triangle 类中设计一个友元函数 operator+(Triangle t1,Triangle t2),它重载运算符“+”, 返回 t1 和 t2 两个三角形的面积之和。 # include # include class Triangle { int x,y,z; double area; public: Triangle (int i, int j,int k); { double s; x=i;y=j;z=k; s=(x+y+z)/2.0; area=sqrt(s*(s-x)*(s-y)*(s-z)); } void disparea() { cout<<”Area=”<<area<<ednl; } }; 3
void main() Triangle t1(3,4,5),t2(4,5,6); double s; cout<<"t1:";t1.disparea); cout<<"t2:";t2.disparea(); s=t1+t2; cout<<”总面积”<<s<<endl, 程序执行结果“ t1:Area=6 t2:Area=9.92157 总面积=15.9216
void main() { Triangle t1(3,4,5),t2(4,5,6); double s; cout<<”t1:”; t1.disparea(); cout<<”t2:”; t2.disparea(); s=t1+t2; cout<<”总面积”<<s<<endl; } 程序执行结果“ t1:Area=6 t2:Area=9.92157 总面积=15.9216 4