最近更新したページ
2013-10-20
2013-09-29
2013-09-23
2012-01-07
2011-11-09
2011-10-23
2011-10-09
2011-10-01
2011-09-29
2011-09-03
2011-08-07
2011-08-02
2011-07-29
2011-07-10
2011-05-05
2011-05-04
2011-04-24
2011-04-13
2011-04-05
2011-03-26
2011-02-18
2011-02-15
2010-12-26
2010-12-07
2010-12-05
2010-11-23
2010-09-28
2010-09-23
2010-08-26
2010-08-22
2010-07-16
2010-01-17
2010-01-11
2009-10-04
2009-08-21
2009-08-13
2009-06-18
2009-06-01
2009-04-29
2009-02-16
2009-02-11
2009-02-03
2008-07-22
2008-07-21
2008-07-15
2008-07-14
2008-07-13
2008-07-12
2008-07-08
2008-07-05
2008-06-28
2008-06-17
2008-06-05
2008-06-02
2008-06-01
2008-05-29
2008-05-26
2008-05-21
2008-05-19
2008-05-18
2007-10-31
2007-10-27
2007-09-28
2007-09-23
2007-09-17
2007-09-16
2007-09-14
2007-09-11
2007-06-18
2007-04-15
2006-12-21
2006-11-30
2006-11-22
2006-08-17
2006-03-29
2006-03-28
2006-03-27

C/C++ 演算子のオーバーロード


C++ 演算子のオーバーロード

 C言語には、演算子のオーバーロードは無い。

 関数のオーバーロードは比較的わかりやすいが、演算子 '+' '-' '=' '<' などのオーバーロード(演算子の多重定義・operater overloading)と一言で言っても兎角判りにくいので別頁作成。

 「関数のオーバーロード」については C/C++ オーバーロード を参照。

演算子の再定義例

 クラス が若干判ったところで演算子オーバーロードの実例。

インクリメント・デクリメントの前置と後置例

#include <iostream>
#include <string>
using namespace std;
class Counter {
   string item;                  // dummy
   int count;                    // inc,dec 対象変数
public :
   Counter& operator++() {       // ++ 前置 の再定義
      ++(this->count);
      return *this;
   }
   Counter operator++(int) {     // 後置 ++ の再定義
      Counter tmp = *this;
      (this->count)++;
      return tmp;
   }
   Counter(string, int);         // コンストラクタ
   Counter& operator=(Counter&); // = の再定義
   int get_count();              // count を取得するメンバ関数
};
void main() {
   Counter temp("a", 0);
   Counter cnt( "b", 0);
   temp = ++cnt ;
   printf("temp:%d cnt:%d \n", temp.get_count(), cnt.get_count());
   temp = cnt++ ;
   printf("temp:%d cnt:%d \n", temp.get_count(), cnt.get_count());
}
※--(デクリメント)も同様に定義すれば利用可能。
※後置はインクリメント(デクリメント)するが、以前の値を戻す...で良い?と思われる。
※operator 定義内、前置・後置は、可読性を意識したのみ。どっちでも...
// 本筋から外れるので外部へ出した関数定義
Counter::Counter(string in_item, int in_count) {
   this->item  = "";
   this->count = in_count;
}
Counter& Counter::operator=(Counter& obj) {
   this->item  = obj.item;
   this->count = obj.count;
   return *this;
}
int Counter::get_count() {
   return this->count;
}

▲上へ [ 編集 ]

簡単な演算子のオーバーロード例


加算なのに乗算される
※こんな使い方普通しないが、返って判りやすい。
class MathInt {
   int val;
public:
   // コンストラクタ
   MathInt(int in_val) {
      this->val = in_val;
   }
   // オペレータ +(プラス) の再定義
   int operator + (MathInt obj) {
      int ret;
      ret = this->val * obj.val;    // this は first_val 側ポインタを表す。
      return ret;
   }
   // オペレータ ^(キャップ) の再定義
   int operator ^ (MathInt obj) {
      int ret;
      ret = (int)pow((double)(this->val),(double)(obj.val));
      return ret;
   }
};
#define VAL1 10
#define VAL2 2
void main() {
   MathInt first_val  = 256;
   MathInt second_val = 2;
   int answer;
   answer = first_val + second_val; // MathInt::operator+(second_val) 実行
   cout << answer << endl;          // なんとも 512 が表示される。
   answer = first_val ^ second_val; // MathInt::operator^(second_val) 実行
   cout << answer << endl;          // 65536 が表示される。
   // 直定数でも良いがプリコンパイラ展開時、優先順位なども要考慮。
   // 指定できるのは当然キャスト可能な値でなければならない。
   answer = ((MathInt)(VAL1))^((MathInt)(VAL2));
   cout << answer << endl;          // 100 が返る。
}
※足し算したのに掛け算される。これをうまく利用して構造体(やクラス)の演算子処理をプログラムコード上自然に扱えるよう再定義することが可能。

▲上へ [ 編集 ]

演算子のオーバーロード

 一般に operator[] などと表現されることが多いように思われる。

 まだ理解が不十分だが、例えば + などの使用時に一定の要件に一致する場合のみ定義済み関数を簡易に呼び出し、あたかも演算子のみで処理されたような記述に見せかけることが出来る...機能...?

 使用するにはクラスの(簡単なレベルでも可?)知識が必要となるらしい。構造体中に記述しても使えるが C++ の構造体が、そもそもクラスの一部である。

演算子の多重定義


 例えば、2の3乗を C/C++ で行う場合、pow((double)2,(double)3) として求めるが、2^3 や 2**3 としたい場合など再定義することで出来るらしい。

 ちなみに、「^」キャップはビット演算子として予約済みなので excel の積りで使用すると期待値が返らない。また、2**3 も微妙な記述だが、変数使用ならポインタ予約演算子。再定義で ** をべき乗とすると一定条件下で意図した計算を行うための簡略的なコーディングとして利用できる。(自然なコーディングが可能(可読性向上)だが、日をあけ、または、人が見ると意味不明(可読性の低下)となることもあり。)

 実際は、通常の関数呼出手順を取らず簡易的に自然なコーディングを行うための記述拡張と思われる。

※こういう書き方していて自分で意味不明。(日を隔てて読むと既に意味不明。)
※「 2^3 又は、2**3 でも 演算子をオーバーロードすれば、2の3乗(べき乗)を求めることが出来ますョ!」ということである。
※ここに至る経緯は、STL の std::sort において「演算子のオーバーロード」の知識が必要(...らしい...)となったためである。

▲上へ [ 編集 ]

リンク


内部リンク


外部リンク


  • 現在ありません

▲上へ [ 編集 ]
2008年07月15日(火) 08:20:39 Modified by cafeboy1




スマートフォン版で見る