C++プログラミング · 3 min read · Oct 12, 2025
C/C++を段階的に学ぶ - ページ15
15. 段階的C/C++ — C++プログラミング - 演算子のオーバーロード
演算子のオーバーロード
| | 1. はじめに
- 演算子
• 演算子オーバーロードのルール
• 演算子オーバーロードの制限 - 単項演算子のオーバーロード
- 二項演算子のオーバーロード
- 文字列の演算子オーバーロード |
1. はじめに
| | // 変数を別の変数に代入
#include
using namespace std;
int main()
{
int a = 10, b;
b = a; // 有効
cout << b;
return 0;
} | // オブジェクトを別のオブジェクトに代入
#include
using namespace std;
class emp
{
public:
int eno;
float sal;
};
int main()
{
emp e1= { 1001, 2300.45 },e2 ;
cout << endl << e1.eno << e1.sal;
e2 = e1; // 有効
cout << endl << e2.eno << e2.sal;
return 0;
} |
式はすべての言語に共通しており、式はオペランドと演算子の集合です。一方、操作は式の集合です。
上記の2つのプログラムは、変数/オブジェクトがどのように一緒に代入されたかを示しています。
両方のプログラムは有効であり、等号演算子 (=) の使用を示しています。
| |
|
|
演算子のオーバーロードは、オブジェクト指向プログラミングの最もエキサイティングな機能の1つです。これは、上記の不正な構造操作のような状況を克服するために使用されます。複雑で不明瞭なプログラムリストを直感的に明らかなものに変えることができます。
演算子のオーバーロードを通じて、通常のC++演算子がユーザー定義データ型に適用されたときに新しい意味を持つことができることがわかります。キーワードoperatorは演算子をオーバーロードするために使用され、結果として得られる演算子はプログラマーが提供した意味を採用します。
例えば、オブジェクトを使用して直接文字列代入操作を実行できます。
| | // 文字列を他の文字列に代入するプログラム
#include
#include
#include
using namespace std;
class string
{
char str;
public:
string() { }
string(char s) { str = s; }
void putstring()
{
cout << str;
}
};
int main()
{
string s1(“Computer”);
string s2;
s2 = s1;
s2.putstring();
return 0;
} |
2. 演算子
type operator operator-symbol ( parameter-list )
operatorキーワードは、クラスのインスタンスに適用されたときにoperator-symbolが何を意味するかを指定する関数を宣言します。これにより、演算子は複数の意味を持つことができ、「オーバーロード」されます。コンパイラはオペランドの型を調べることによって、演算子の異なる意味を区別します。
演算子オーバーロードのルール
- 次の演算子をオーバーロードできます:
| + | - | * | / | % | ^ | |
| ! | = | < | > | += | –= |
| | ^= | &= | |= | << | >> | <<= | | | <= | >= | && | || | ++ | –– | | | ( ) | [ ] | new | delete | & | | | | | ~ | = | /= | %= | >>= | == | | | != | , | –> | –> | | |
演算子が単項演算子または二項演算子のいずれかとして使用できる場合、各使用を別々にオーバーロードできます。
演算子をオーバーロードするには、非静的メンバー関数またはクラスの友達であるグローバル関数を使用できます。グローバル関数は、クラス型またはクラス型の参照の少なくとも1つのパラメータを持っている必要があります。
単項演算子がメンバー関数を使用してオーバーロードされる場合、引数は取られません。グローバル関数を使用してオーバーロードされる場合、1つの引数を取ります。
二項演算子がメンバー関数を使用してオーバーロードされる場合、1つの引数を取ります。グローバル関数を使用してオーバーロードされる場合、2つの引数を取ります。
演算子オーバーロードの制限
新しい演算子を定義することはできません、例えば**.
演算子の優先順位やグルーピングを変更することはできず、受け入れるオペランドの数を変更することもできません。
組み込みデータ型に適用されたときの演算子の意味を再定義することはできません。
オーバーロードされた演算子はデフォルト引数を取ることができません。
いかなるプリプロセッサシンボルもオーバーロードできず、次の演算子をオーバーロードすることもできません:
| | . | .* | :: | ?: |
代入演算子には追加の制限があります。これは、友達関数としてではなく、非静的メンバー関数としてのみオーバーロードできます。これは、継承できない唯一の演算子であり、派生クラスは基底クラスの代入演算子を使用できません。
3. 単項演算子のオーバーロード
単項演算子のオーバーロードから始めましょう。単項演算子は1つのオペランドのみに作用します。( オペランドは単に演算子によって作用される変数です)。単項演算子の例には、インクリメント演算子++とデクリメント演算子–、および単項マイナスがあります。
例:
次の例は、インクリメント演算子++の使用を示しています。
| | #include
using namespace std;
class counter
{
private:
unsigned int count;
public:
counter(){ count = 0; }
int get_count() { return count; }
counter operator ++()
{
count++;
counter temp;
temp.count = count;
return temp;
}
};
int main()
{
counter c1, c2; // c1 = 0, c2 = 0
cout << “\nC1 = “ << c1.get_count(); // 表示
cout << “\nC2 = “ << c2.get_count();
++c1; // c1 = 1
c2 = ++c1 ; // c1 = 2, c2 = 2
cout << “\nC1 = “ << c1.get_count(); // 再表示
cout << “\nC2 = “ << c2++.get_count(); // c2 = 3
return 0;
} |
もう1つの例として単項マイナスのオーバーロード。
| | #include
using namespace std;
class subtract
{
int a;
int b;
public:
void getdata(int x, int y)
{
a = x; b = y;
}
void putdata()
{
cout<< endl << “A = “ << a <<”B = “ << b;
}
void operator -()
{
a = -a; b = -b;
}
};
int main()
{
subtract s;
s.getdata(34, -6);
cout << endl << “S : “;
s.putdata();
-s;
cout << endl << “S : “;
s.putdata();
return 0;
}
|
4. 二項演算子のオーバーロード
しかし、演算子は単項演算子と同じように簡単にオーバーロードできます。 算術演算子、比較演算子、および算術代入演算子をオーバーロードする例を見ていきます。
単項演算子のオーバーロード方法を見てきました。同じメカニズムを使用して二項演算子をオーバーロードできます。
| | // +演算子のオーバーロード
#include
using namespace std;
class time
{
int hh; int mm; int ss;
public:
time( ) { }
time(int h, int m, int s)
{
hh =h; mm = m; ss = s;
}
void disp_time()
{
cout << endl << hh<< “ : “
<< mm << “ : “ << ss;
}
time operator+(time);
};
time time::operator+(time t)
{
time temp;
temp.hh = hh + t.hh;
temp.mm = mm + t.mm;
temp.ss = ss + t.ss;
return temp;
}
int main()
{
time t1(12,1,24) , t2(5, 23, 45), t3;
t3 = t1 + t2;
t3.disp_time();
return 0;
} |
5. 文字列の演算子オーバーロード
C/C++は文字列をかなり異なる方法で扱います。他の言語のように演算子を使用して文字列をコピー、連結、または比較することはありません。C/C++には、上記の操作を実行するための組み込み関数があります。しかし、C++は演算子を使用して文字列に対してすべてを実行する機能を提供します。つまり、演算子にそのようなことを実行するための追加の責任を提供する必要があります。
次の例は、比較演算子==を使用して2つの文字列を比較することを示しています。
| | // 演算子オーバーロードを使用して2つの文字列を比較するプログラム
#include
#include
#include
using namespace std;
enum boolean{ false, true };
class string
{
char str;
public:
string() { str = NULL; }
string(char *s) { str = s; }
int operator ==(string ts)
{
if (strcmp(str, ts.str) >= 0)
return true;
else
return false;
}
};
int main()
{
string s1(“Computer”);
string s2(“Computers”);
if(s1 == s2)
cout << “Equal”;
else
cout << “Not Equal”;
return 0;
} |
| | // 2つの文字列の連結
#include
#include
#include
using namespace std;
class string
{
char str;
public:
string()
{
str = new char[30] ; str = NULL;
}
string(char *s) { str = s; }
string operator +(string ts)
{
string t;
strcat(t.str, str);
strcat(t.str, ts.str);
return t;
}
void putstring()
{
cout << endl << str;
}
};
int main()
{
string s1(“Computer”); string s2(“Institute”);
s1.putstring(); s2.putstring();
string s3;
s3 = s1 + s2;
s3.putstring();
return 0;
} |
参考文献: Turbo C++におけるオブジェクト指向プログラミング: ロバート・ラフォーレ
新しい投稿を受信箱で受け取る
スパムはありません。いつでも購読を解除できます。