3-3-0. オーバーロード

公開日: 17:50 3. オブジェクト指向編/3-3. オーバーロード/3-3-0. オーバーロード

C++では同じスコープ内で関数名演算子を複数定義する事が可能で、これは関数のオーバーロード演算子のオーバーロードと呼ばれます。

オーバーロード宣言は同一スコープ内で前に宣言された宣言と同じ名前を持つ宣言で、異なる点は引数と定義(実装)です。

オーバーロードされた関数や演算子を呼び出すとき、コンパイラは呼び出した時の型と定義で指定された引数の型を比較して適切な定義を決定します。最も適切な関数や演算子を選択する処理はオーバーロード解決と呼ばれます。

関数のオーバーロード

スコープ内で同じ関数名を複数定義することができます。関数の定義は引数の型と数がそれぞれ異なる必要があります。戻り値の型だけが違う関数宣言をオーバーロードすることはできません。 

以下は異なるデータ型を出力するprint関数の例です。
#include <iostream>
using namespace std;
 
class printData 
{
   public:
      void print(int i) {
        cout << "整数の出力: " << i << endl;
      }

      void print(double  f) {
        cout << "実数の出力: " << f << endl;
      }

      void print(char* c) {
        cout << "文字列の出力: " << c << endl;
      }
};

int main(void)
{
   printData pd;
 
   // 整数の出力を呼び出し
   pd.print(5);
   // 実数の出力を呼び出し
   pd.print(500.263);
   // 文字列の出力を呼び出し
   pd.print("Hello C++");
 
   return 0;
}
上のコードをコンパイルし実行すると、次の結果が得られます。
整数の出力: 5
実数の出力: 500.263
文字列の出力: Hello C++

演算子のオーバーロード

C++で利用可能な組み込み演算子の殆どをオーバーロードまたは再定義することが可能です。従って、プログラマは演算子をユーザ定義型のように利用できます。

演算子のオーバーロードは特別な名前の関数であり、operatorキーワードの後ろに定義される演算子の記号が続きます。他の関数と同様に、演算子のオーバーロードは戻り値と引数リストを持ちます。
Box operator+(const &Box);
2つのBoxオブジェクトを加算し、計算後のBoxオブジェクトを返す加算演算子(+)を宣言します。殆どの演算子のオーバーロードはメンバでない通常の関数、またはクラスのメンバ関数として定義されます。上記の関数をクラスの非メンバ関数として定義した場合、次のように被演算子として2つの引数を渡す必要があります。
Box operator+(const Box&, const Box&);
次の例はメンバ関数を使った演算子のオーバーロードのコンセプトを示します。ここでの目的は、渡した引数であるオブジェクトを使って中身にアクセスされることであり、this演算子を呼び出すオブジェクトがthis演算子を使ってアクセスされることです。
#include <iostream>
using namespace std;

class Box
{
   public:

      double getVolume(void)
      {
         return length * breadth * height;
      }
      void setLength( double len )
      {
          length = len;
      }

      void setBreadth( double bre )
      {
          breadth = bre;
      }

      void setHeight( double hei )
      {
          height = hei;
      }
      // +演算子をオーバーロードして2つのBoxオブジェクトを加算
      Box operator+(const Box& b)
      {
         Box box;
         box.length = this->length + b.length;
         box.breadth = this->breadth + b.breadth;
         box.height = this->height + b.height;
         return box;
      }
   private:
      double length;      // boxの縦幅
      double breadth;     // boxの横幅
      double height;      // boxの深さ
};
// プログラムの開始
int main( )
{
   Box Box1;                // Box型のBox1を宣言
   Box Box2;                // Box型のBox2を宣言
   Box Box3;                // Box型のBox3を宣言
   double volume = 0.0;     // 体積を保存
 
   // box 1の仕様
   Box1.setLength(6.0); 
   Box1.setBreadth(7.0); 
   Box1.setHeight(5.0);
 
   // box 2の仕様
   Box2.setLength(12.0); 
   Box2.setBreadth(13.0); 
   Box2.setHeight(10.0);
 
   // box 1の体積
   volume = Box1.getVolume();
   cout << "Box1の体積 : " << volume <<endl;
 
   // box 2の体積
   volume = Box2.getVolume();
   cout << "Box2の体積 : " << volume <<endl;

   // 2つのBoxオブジェクトを加算
   Box3 = Box1 + Box2;

   // box 3の体積
   volume = Box3.getVolume();
   cout << "Box3の体積 : " << volume <<endl;

   return 0;
}
上のコードをコンパイルし実行すると、次の結果が得られます。
Box1の体積 : 210
Box2の体積 : 1560
Box3の体積 : 5400

オーバーロード可能/不可な演算子

次のリストはオーバーロード可能な演算子です。
+-*/%^
&|~!,=
<><=>=++--
<<>>==!=&&||
+=-=/=%=^=&=
|=*=<<=>>=[]()
->->*newnew[]deletedelete []

次のリストはオーバーロード不可な演算子です。
::.*.?:

演算子のオーバーロードのサンプル

次のリストは様々な演算子のオーバーロードの使用例です。
S/N演算子
1単項演算子のオーバーロード
2二項演算子のオーバーロード
3関係演算子のオーバーロード
4入出力演算子のオーバーロード
5++/--演算子のオーバーロード
6代入演算子のオーバーロード
7関数呼び出し演算子()のオーバーロード
8添字演算子のオーバーロード
9メンバアクセス演算子->のオーバーロード
  • ?±??G???g???[?d????u?b?N?}?[?N???A

0 件のコメント :

コメントを投稿