对运算符重载和友元函数的例子

以下是博主在学习完运算符重载和友元函数后编写的一个例子,实现一个复数的基本运算。
定义的头文件:

/******************************************************************
        complex.h                     Defination of the complex
******************************************************************/

#ifndef _complex_
#define _complex_
#include<cmath>
#include<iostream>
using std::sqrt ;
using std::ostream;   // Error :    ‘ostream’ does not name a type
using std::istream; 

class Complex{
private:
double real ;
double imag ;
public:
Complex( double real=0 , double imag=0 ) { this->real = real ;   this->imag = imag ; }
void zero() {   real = imag = 0 ; }
double module() {   return sqrt(real*real+imag*imag); }
double angle()  {   return atan2(imag,real); }

//     operator overloading
/******************************************************/

Complex operator+(const Complex & com) const;
Complex operator-(const Complex & com) const;
Complex operator*(const Complex & com) const ;
Complex operator/(const Complex & com) const;
Complex operator~() const;
/*******************************************************/

/******************************************************************/
//    template overloading  for the general operation of built-in type 

 Complex operator+(double value);
 Complex operator-(double value);
 Complex operator*(double value);
 Complex operator/(double value);

//   friend functions
friend ostream & operator<<( ostream & os ,  Complex & com );
friend Complex operator+( double value , Complex & com );
friend istream & operator>>( istream & is ,  Complex & com );

friend Complex operator+( double value , Complex & com );
friend Complex operator-( double value , Complex & com );
friend Complex operator*( double value , Complex & com );
friend Complex operator/( double value , Complex & com );

};
#endif

实现的文件:

/***********************************************
             Realization of the Complex
************************************************/

#include "complex.h"
#include <iostream>
using std::ostream;
using std::istream;
/*
    Complex( double real=0 , double imag=0 ) { this->real = real ;   this->imag = imag ; }
    void zero() {   real = imag = 0 ; }
    double module() {   return sqrt(real*real+imag*imag); }
    double angle()  {   return atan2(imag,real); }

    //     Operator overloading

Complex operator+(const Complex & com) const;
Complex operator-(const Complex & com) const;
Complex operator*(const Complex & com) const ;
Complex operator/(const Complex & com) const;
Complex operator~() const;

//      Template overloading  for the general operation of built-in type
 Complex operator+(double value);
 Complex operator-(double value);
 Complex operator*(double value);
 Complex operator/(double value);

//      Friend functions
friend ostream & operator<<( ostream & os ,  Complex & com );
friend Complex operator+( double value , Complex & com );
friend istream & operator>>( istream & is ,  Complex & com );
friend Complex operator+( double value , Complex & com );
friend Complex operator-( double value , Complex & com );
friend Complex operator*( double value , Complex & com );
friend Complex operator/( double value , Complex & com );

*/

/***********************************************************
        Operator Overloading
***********************************************************/

Complex Complex::operator+(const Complex & com) const{
    Complex result ;
    result.real = this->real + com.real ;
    result.imag = this->imag + com.imag ;
    return result ;
}

Complex Complex::operator-(const Complex & com) const{
    Complex result ;
    result.real = this->real - com.real ;
    result.imag = this->imag - com.imag ;
    return result ;
}   

Complex Complex::operator*(const Complex & com) const{
    Complex result ;
    result.real = (this->real) * com.real - (this->imag*com.imag);
    result.imag = this->real*com.imag + this->imag*com.real ;
    return result ;
}

Complex Complex::operator/(const Complex & com) const{
    Complex result ;
    result.real = (this->real*com.real + this->imag*com.imag)/(com.real*com.real+com.imag*com.imag);
    result.real = (this->imag*com.real - this->real*com.imag)/(com.real*com.real+com.imag*com.imag);
    return result ;
}

Complex Complex::operator~()const{
    Complex result ;
    result.real = (this->real) ;
    result.imag = -this->imag  ;
    return result ;
}

/*******************************************************************************
    Template overloading  for the general operation of built-in type
********************************************************************************/

Complex Complex::operator+(double value){
    Complex result ;
    result.real = this->real+value;
    result.imag = this->imag;

    return result ;
}

Complex Complex::operator-(double value){
    Complex result ;
    result.real = this->real-value;
    result.imag = this->imag;

    return result ;
}

Complex Complex::operator*(double value){
    Complex result ;
    result.real = this->real*value;
    result.imag = this->imag*value;

    return result ;
}

Complex Complex::operator/(double value){
    Complex result ;
    result.real = this->real/value;
    result.imag = this->imag/value;

    return result ;
}

/**********************************************************
             friend functions
***********************************************************/
ostream & operator<<( ostream & os ,  Complex & com ){
    os<<com.real<<‘+‘<<com.imag<<‘j‘;
    return os ;
}

istream & operator>>( istream & is ,  Complex & com ){
    std::cout<<"Enter the real part :";
    is>>com.real;
    is.clear();
    std::cout<<"Enter the image part:";
    is>>com.imag;

    return is ;
}

//    Behold this part , Never get the Istream wrong again !!!!!

Complex operator+( double value , Complex & com ){
    Complex result ;
    result.real = com.real+value;
    result.imag = com.imag;

    return result ;
}

Complex operator-( double value , Complex & com ){
    Complex result ;
    result.real = com.real-value;
    result.imag = com.imag;

    return result ;
}

Complex operator*( double value , Complex & com ){
    Complex result ;
    result.real = com.real*value;
    result.imag = com.imag*value;

    return result ;
}

Complex operator/( double value , Complex & com ){
    Complex result ;
    result.real = com.real/value;
    result.imag = com.imag/value;

    return result ;
}

测试文件:
#include "complex.h"
#include<iostream>

using namespace std ;

int main(){
    Complex a(3.0,4.0);
    Complex c ;
    Complex result ;

    while( std::cin>>c )
    {
        std::cout<<" c is "<<c<<‘\n‘;
        std::cout<<" complex conjugate is "<<(result=~c)<<‘\n‘;
        std::cout<<" a is "<<a<<‘\n‘;
        std::cout<<" a + c is "<<(result=a+c)<<‘\n‘;
        std::cout<<" a - c is "<<(result=a-c)<<‘\n‘;
        std::cout<<" a * c is "<<(result=a*c)<<‘\n‘;
        std::cout<<" a / c is "<<(result=a/c)<<‘\n‘;
        std::cout<<" the mod   of c is "<<c.module()<<‘\n‘;
        std::cout<<" the angle of c is "<<c.angle()<<‘\n‘;
    }

    return 0 ;
}

在编写时,博主遇到了一个问题:
invalid initialization of non-const reference of type ‘Complex&’ from an rvalue of type ‘Complex’
这是由于函数的返回是一个暂时的量所导致的,所以需要将结果用一个变量保存起来,否则就会报错。
因此就有了以上的写法:(result=a/c)
关于这个问题可以参考:https://blog.csdn.net/u011068702/article/details/64443949

原文地址:http://blog.51cto.com/13824643/2133140

时间: 2024-10-24 20:17:02

对运算符重载和友元函数的例子的相关文章

C++运算符重载为友元函数学习笔记

初探C++运算符重载学习笔记 在上面那篇博客中,写了将运算符重载为普通函数或类的成员函数这两种情况. 下面的两种情况发生,则我们需要将运算符重载为类的友元函数 <1>成员函数不能满足要求 <2>普通函数又不能访问类的私有成员时 举例说明: class Complex{ double real, imag; public: Complex(double r, double i):real(r), imag(i){ }; Complex operator+(double r); };

C++运算符重载(友元函数方式)

我们知道,C++中的运算符重载有两种形式:①重载为类的成员函数(见C++运算符重载(成员函数方式)),②重载为类的友元函数. 当重载友元函数时,将没有隐含的参数this指针.这样,对双目运算符,友元函数有2个参数,对单目运算符,友元函数有一个参数.但是,有些运行符不能重载为友元函数,它们是:=,(),[]和->. 重载为友元函数的运算符重载函数的定义格式如下: [cpp] view plaincopy 一.程序实例 [cpp] view plaincopy 1 //运算符重载:友元函数方式 2

运算符重载为友元函数,或者普通函数

重载为友元函数时,一般先在类内用friend关键字声明,然后在类外具体实现(具体实现时不需friend,也不需类名) 重载为普通函数时,直接在类外给出函数实现即可(也不需要类名): 二者的区别在于友元函数对类的数据成员有直接获取权限,而普通函数还要通过类的接口访问数据成员. 还有一种是运算符重载为类的成员函数.同友元类似,成员也有直接访问私有数据成员的权限. 那么什么时候重载为成员,什么时候重载为友元呢?

运算符重载和友元函数

1. 运算符重载 c++允许将运算符重载扩展到用户定义的类型,例如:允许使用+将两个对象相加,编译器将根据操作数的数目和类型决定使用哪种加法定义,重载运算符可以使代码看起来更加自然. 例:计算时间,一个运算符重载的实例: class Time { private: int hours; int minutes; public: Time() {} Time(int hours, int minutes) { this->hours = hours; this->minutes = minute

初探C++运算符重载学习笔记&amp;lt;2&amp;gt; 重载为友元函数

初探C++运算符重载学习笔记 在上面那篇博客中,写了将运算符重载为普通函数或类的成员函数这两种情况. 以下的两种情况发生.则我们须要将运算符重载为类的友元函数 <1>成员函数不能满足要求 <2>普通函数又不能訪问类的私有成员时 举例说明: class Complex{ double real, imag; public: Complex(double r, double i):real(r), imag(i){ }; Complex operator+(double r); };

C++运算符重载(成员函数方式)

一.运算符重载 C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作.如果将C++中这些现存的运算符直接作用于用户自定义的类型数据上,会得到什么样的结果呢?编译器无法给出正常的结果,因为我们需要运算符重载,给运算符赋予多重含义,使同一个运算符作用于不同类型的数据导致不同类型的行为,增强了运算符的普适性. 运算符重载的实质是函数重载.在实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型

C++ Primer 学习笔记_26_操作符重载与转换(1)--可重载/不可重载的操作符、成员函数方式重载、友元函数方式重载

C++ Primer 学习笔记_26_操作符重载与转换(1)--可重载/不可重载的操作符.成员函数方式重载.友元函数方式重载 引言: 明智地使用操作符重载可以使类类型的使用像内置类型一样直观! 一.重载的操作符名 像任何其他函数一样,操作符重载函数有一个返回值和一个形参表.形参表必须具有操作符数目相同的形参.比如赋值时二元运算,所以该操作符函数有两个参数:第一个形参对应着左操作数,第二个形参对应右操作数. 大多数操作符可以定义为成员函数或非成员函数.当操作符为成员函数时,它的第一个操作数隐式绑定

运算符重载为成员函数

运算符重载实质上就是通过函数重载,重载为成员函数,它就可以自由的访问本类的数据成员,实际使用时,总是通过该类的某个对象来访问重载的运算符.如果是双目运算符,左操作数是对象本身的数据,由this指针指出,就不再需要任何参数.下面分别介绍这两种情况. 对于双目运算符B,如果要重载为类的成员函数,使之能够实现表达式oprd1 B oprd2,其中oprd1为A类的对象,则应当把B重载为A类的成员函数,该函数只有一个形参,形参的类型是oprd2所属的类型.经过重载之后,表达式就相当于函数调用orpd.o

C++——运算符的重载---以成员函数方式重载---以友元函数方式重载

一.运算符的重载 1.运算符的重载 允许把标准运算符(如+ - * /等运算符)应用于自定义数据类型的对象,可以提高程序的可读性,运算符的重载本质上还是函数重载.运算符仅仅是语法上的方便,它是另一种函数调用的方式,只有在设计涉及的代码更容易写,尤其是更容易读的时候才有必要重载. 2.实现运算符重载的方式 类的成员函数 友元函数(即类外的普通函数) 3.运算符重载的原则: 不能重载的运算符有5个:  .  .*  ?: ::  sizeof 运算符重载不允许发明新的运算符 不能改变运算符操作对象的