演算子のオーバーロードの動作確認で以下のコードを実行してみた。
operator+(int) は if 0 しておく。
#include<iostream>
class myInteger {
int value;
public:
int operator + ( myInteger obj ) {
return this->value + obj.value;
}
#if 0
int operator + ( int num ) {
return this->value + num;
}
#endif
myInteger(int value) { this->value = value; }
};
int main() {
myInteger obj1(10), obj2(50);
int num = 5;
std::cout << obj1 + obj2 << std::endl;
std::cout << obj1 + num << std::endl;
return 0;
}
結果は、
root@2af9a6fb2cb6:/cpp/operatpr# g++ -g -O0 operator.cpp
root@2af9a6fb2cb6:/cpp/operatpr# ./a.out
60
15
root@2af9a6fb2cb6:/cpp/operatpr#
ん?実行できちゃった。
obj1 + num
はコンパイル時か実行時にエラーになると思ったのだけれど。
gdb でも確認してみる。
(gdb) p obj1 + obj2
$1 = 60
(gdb) p obj1 + num
Cannot resolve function operator+ to any overloaded instance
(gdb) p obj1 + 5
Cannot resolve function operator+ to any overloaded instance
(gdb)
こちらは予想通り。
ちなみに、operator.cpp の if 0 を有効にした場合は、
(gdb) p obj1 + obj2
$1 = 60
(gdb) p obj1 + num
$2 = 15
(gdb) p obj1 + 5
$3 = 15
(gdb)
となり、これは想定通りの動作。
もうちょっと調べてみる。
コメントで丁寧に教えていただきました。
ありがとうございます。
原因:暗黙の型変換によるもの
暗黙の型変換で使われているコンストラクタをecplicit 修飾で修飾する
explicit myInteger(int value) { this->value = value; }
operator.cpp: In function 'int main()':
operator.cpp:21:23: error: no match for 'operator+' (operand types are 'myInteger' and 'int')
std::cout << obj1 + num << std::endl;
~~~~~^~~~~
operator.cpp:5:9: note: candidate: int myInteger::operator+(myInteger)
int operator + ( myInteger obj ) {
^~~~~~~~
operator.cpp:5:9: note: no known conversion for argument 1 from 'int' to 'myInteger'
コンパイルで弾かれた。当初期待していた動作となった。
左辺も受け取りたい
メンバ関数での演算子のオーバーロードでは引数は1つしか受け取れない。
メンバ関数ではprivateメンバにアクセスできるようにしておいて、
非メンバ関数で2項を受け取る関数を定義する
class myInteger {
int value;
public:
myInteger &operator +=(const myInteger &r) {
value += r.value;
return *this;
}
myInteger &operator +=(int r) {
value += r;
return *this;
}
explicit myInteger(int value) { this->value = value; }
};
// クラス同士
const myInteger operator+(const myInteger& l, const myInteger& r) {
return myInteger(l) += r;
}
// 左辺がint
const myInteger operator+(int l, const myInteger& r) {
return myInteger(r) += l;
}
// 右辺がint
const myInteger operator+(const myInteger& l, int r) {
return myInteger(l) += r;
}