(39.1)演算子リロードの演算子リロードの概念と実現

40097 ワード

文書ディレクトリ
  • 1.演算子リロードの概念
  • 2.演算子をクラスに再ロードするメンバー関数
  • 3.演算子は友元関数
  • に再ロードされます.
    1.演算子のリロードの概念
  • 演算子リロードとは、既存の演算子を再定義し、異なるデータ型に適応するための別の機能を付与することである.
  • いわゆる重荷は、新たな意味を与えることである.たとえば、関数のリロードは、既存の関数に新しい機能を付与します.
  • C++言語自体には、<>演算子など多くの演算子がリロードされています.
  • C++では、プログラマがほとんどの演算子を再ロードし、演算子がコンテキスト環境に合致するようにします.リロード演算子のタスクは、明示的な関数呼び出しによっても実行できますが、演算子リロードを使用すると、プログラムがより明確になることがよくあります.
  • 本質的には、演算子のリロードは関数のリロードである.リロード演算子は、
  • という特殊な名前の関数を使用します.
         operator    (      )
    {
    	   
    }
    operator          ,        。
               “operator    ” 。
    
  • eg:
  • class complex//   
    {
    	public:
    		complex(double r=0.0,double i=1.0);//    
    		{
    			real=r;
    			image=i;
    		}
    	private:
    		double real;//  
    		double image;//  
    }
    
  • 複数クラスの加算に'+'を使用します.演算子関数のプロトタイプは、
  • です.
    complex operator+(const complex &a,const complex &b);
    
    
          
    c3           0
    
  • 演算子関数を呼び出す形式は、
  • です.
    operator     (    )
  • 例えば、complex c 1(1,2)、c 2(3,4)、c 3;c3=operator +(c1,c2); 以上は仕様の演算子関数呼び出し方法であるが、プログラマーはc 3=c 1+c 2と書くのが好きである.
  • リロード演算子のルール(1)C++のほとんどの演算子はリロードできます.リロードできない演算子は:.*::?:sizeof?:条件演算子です(2)演算子の優先度、結合型、演算オブジェクトの数を変更できません.(3)演算子リロード関数ではデフォルトのパラメータは使用できません.(4)リロード演算子にはクラスオブジェクトが必要です.(またはクラスオブジェクトの参照)のパラメータは、すべてC++の組み込みデータ型ではありません.(5)一般的に演算結果を左とすると戻りタイプが参照型となります.演算結果を右とするとオブジェクトが戻ります.(6)演算子のリロード機能は元の機能と一致するはずです.
  • 2.演算子をクラスのメンバー関数に再ロードする
  • 演算子をクラスのメンバー関数として再ロードします.一般的な形式は:
  • です.
    class   { //  
    	……
    	     operator     (      )
    	{
    		   
    	}…
    	…
    }or
    class   { //  
    	……
    	     operator     (      );
    	……
    }::operator     (      )
    {
    	   
    }
    
  • 演算子がメンバー関数に再ロードされると、演算子関数の形式パラメータの個数は、演算子によって規定された演算対象の個数よりも1つ少ない.なぜなら、クラスの非静的メンバー関数には隠しthisポインタがあり、演算子関数はthisポインタでクラスオブジェクトのメンバーに暗黙的にアクセスできるため、このオブジェクト自体のデータは直接アクセスでき、パラメータリストに入れて渡す必要はなく、少ない演算オブジェクトはそのオブジェクト自体である.
  • 1.バイナリ演算子はクラスのメンバー関数として再ロードされます.形式は次のとおりです.
  •        ::operator op(const      &obj2)
    {
    	…… //this    obj1    
    }
    
         ,     “obj1 op obj2”
       obj1.operator op(obj2)
    
  • eg:複数のクラスを設計し、そのクラスオブジェクトの加算と減算を実現する.
  • #include 
    using namespce std;
    class complex//   
    {
    	public:
    		complex(double r=0.0,double i=0.0)//    
    		{
    			real=r;
    			imag=r;
    		}
    		complex operator +(complex &c2);//  +   
    		complex operator -(complex &c2);//  -   
    		void display()
    		{
    			cout<<real<<"+"<<imag<<"i"<<endl;
    		}
    	private:
    		double real;//  
    		double imag;//  
    };
    
    
    complex complex::operator +(complex &c2)
    {
    	complex c;
    	c.real=c2.real+real;//   real      operator +   
    	c.image=c2.imag+imag;
    	return c;
    }
    complex complex::operator -(complex &c2)
     { 
    	complex c;
    	c.real=real-c2.real; //      
    	c.imag=imag-c2.imag;
    	return c;
     }
    int main()
    { 
    	complex c1(1,2),c2(3,4),c3;
    	c3=c2+c1; //  operate +
    	c3.display(); //  4+6i
    	
    	c3=c2-c1; 
    	c3.display(); //  2+2i
    	return 0;
     }
    
  • 2.前置単項演算子はクラスのメンバー関数として再ロードされます.形式は次のとおりです:
  •        ::operator op()
    {
    	…… //this    obj    
    }
    
         ,     “op obj”
       obj.operator op()
    
  • eg:複数クラスの前置自己増加演算を実現する.
  • #include 
    using namespace std;
    class complex//   
    {
    	public:
    		complex(double r=0.0,double i=0.0)//    
    		{
    			real=r;
    			imag=i;
    		}
    		complex operator ++();//    ++,         
    		void display()
    		{
    			cout <<real<<"+"<<imag<<i<<endl;
    		}
    	private:
    		double real;//  
    		double imag;//  
    };
    
    complex complex::operator ++()
    {
    	complex a;
    	real++;//  operate ++   
    	imag++;
    	a.real=real;
    	a.imag=imag;
    	return a;
     }
     int main()
     {
    	complex c1(1,2),c2;
    	c2=++c1;//  ++
    	c1.display(); //  2+3i
    	c2.display(); //  2+3i
     return 0;
     }
    
  • 3.後置単項演算子はクラスのメンバー関数として再ロードされ、形式は以下の通りである:
  •        ::operator op(int)//int     
    {
    	…… //this    obj    
    }
         ,     “obj op”
       obj.operator op(0)
    
  • eg:複数クラスの後置自増演算を実現する.
  • #include 
    using namespace std;
    class complex//   
    {
    	public:
    		complex(double r=0.0,double i=0.0)//    
    		{
    			real=r;
    			imag=i;
    		}
    		complex operator ++();//    ++,         
    		void display()
    		{
    			cout <<real<<"+"<<imag<<i<<endl;
    		}
    	private:
    		double real;//  
    		double imag;//  
    };
    
    complex complex::operator ++()
    {
    	complex a;
    	a.real=real;
    	a.imag=imag;
    	real++;//  operate ++   
    	imag++;
    	return a;
     }
     int main()
     {
    	complex c1(1,2),c2;
    	c2=c1++;//  ++
    	c1.display(); //  2+3i
    	c2.display(); //  1+2i
     	return 0;
     }
    

    3.演算子を友元関数に再ロードする
  • 演算子が友元関数に再ロードされると、演算子関数の形式パラメータの個数と演算子が規定する演算対象個数が一致する.クラスのメンバー関数ではなく、一般的な関数
  • です.
  • の形式は以下の通りである:
  • class   
    { //  
    	……
    	//    
    	friend      operator     (      )};
         operator     (      )
    {
    	   
    }
    
  • 1.両目演算子はクラスの友元関数として再ロードされ、形式は以下の通りである:
  •      operator op(const      &obj1,const      &obj1)
    {
    	…… // obj1 obj2          
    }
    
         ,     “obj1 op obj2”
       operator op(obj1,obj2)
    
  • eg:減算演算子を複数クラスの友元関数に再ロードします.
  •  #include 
    using namespace std;
    class complex //   
     {
    	 public:
    		 complex(double r=0.0,double i=0.0) {real=r; imag=i;}//    
    		 friend complex operator +(const complex &c1,const complex &c2);
    		//  +   ,operator +        ,          
    		 friend complex operator -(const complex &c1,const complex &c2);
    		//  -   
    		 void display()
    		 { 
    		 	cout<<real<<"+"<<imag<<"i"<<endl; 
    		 }
    	 private:
    		 double real; //  
    		 double imag; //  
     };
    
     complex operator +(const complex &c1,const complex &c2)
     { 
    	 complex c3;
    	 c3.real=c1.real+c2.real;
    	 c3.imag=c1.imag+c2.imag;
    	 return c3;
     }
     complex operator -(const complex &c1,const complex &c2)
     { 
    	 complex c3;
    	 c3.real=c1.real-c2.real;
    	 c3.imag=c1.imag-c2.imag;
    	 return c3;
     }
     int main()
     { 
    	 complex c1(1,2),c2(3,4),c3;
    	 c3=c2+c1; 
    	 c3.display(); //  4+6i
    	 
    	 c3=c2-c1; 
    	 c3.display(); //  2+2i
    	 return 0;
     }
    
    
  • 2.前置単項演算子はクラスの友元関数として再ロードされ、形式は以下の通りである:
  •      operator op(const      &obj)
    {
    	…… // obj      
    }
    
         ,     “op obj2
       operator op(obj)
    
  • 3.後置単項演算子はクラスの友元関数として再ロードされ、形式は以下の通りである:
  •      operator op(const      &obj,int)
    {
    	…… // obj      
    }
    
         ,     “obj op“
       operator op(obj,0)
    
  • eg:前置自増演算子と後置自増演算子を複数クラスの友元関数に再ロードします.
  • #include 
    using namespace std;
    class complex //   
    {
    	 public:
    		 complex(double r=0.0,double i=0.0){real=r; imag=i;}//    
    		 friend complex operator ++(complex &c1); //    ++,operator ++         
    		 friend complex operator ++(complex &c1,int); //    ++
    		 void display()
    		 {
    		 	cout<<real<<"+"<<imag<<"i"<<endl;
    		 }
    	private:
    		double real; //  
    		double imag; //  
    };
    
     complex operator ++(complex &c1)
     {
    	complex c;
    	c1.real++;
    	c1.imag++;
    	c.real=c1.real;
    	c.imag=c1.imag;
    	return c;
     }
     complex operator ++(complex &c1,int)
     {
    	complex c;
    	c.real=c1.real;
    	c.imag=c1.imag;
    	c1.real++;
    	c1.imag++;
    	return c;
    }
    
     int main()
     {
    	complex c1(1,2),c2,c3;
    	c2=++c1;
    	c1.display(); //  2+3i
    	c2.display(); //  2+3i
    	c3=c1++;
    	c1.display(); //  3+4i
    	c3.display(); //  2+3i
    	return 0;
     }