ページ 1 / 1
演算子多重定義が必要な理由
Posted: 2015年8月14日(金) 14:12
by 23120b
ベクトルを使った下記サンプルコードで演算子オーバーロード(11,17,22行目)が必要な理由が分かりません。
どなたかご教授頂けないでしょうか。よろしくお願いします。
オーバーロードしなくてもビルドは通っています。
コード:
// ベクトルにクラスオブジェクトを保存する
#include <iostream>
#include <vector>
using namespace std;
class Demo {
double d;
public:
Demo() { d = 0.0; }
Demo(double x) { d = x; }
Demo &operator=(double x) {
d = x; return *this;
}
double getd() { return d; }
};
bool operator<(Demo a, Demo b)
{
return a.getd() < b.getd();
}
bool operator==(Demo a, Demo b)
{
return a.getd() == b.getd();
}
int main()
{
vector<Demo> v;
int i;
for(i=0; i<10; i++)
v.push_back(Demo(i/3.0));
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
for(i=0; i<v.size(); i++)
v[i] = v[i].getd() * 2.1;
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
return 0;
}
Re: 演算子多重定義が必要な理由
Posted: 2015年8月14日(金) 14:19
by みけCAT
23120b さんが書きました:ベクトルを使った下記サンプルコードで演算子オーバーロード(11,17,22行目)が必要な理由が分かりません。
他のサンプルコードでは必要かもしれませんが、確かにこのサンプルコードでは必要ないですね。
YAGNI原則に基づき、消してもいいかもしれません。
コード:
// ベクトルにクラスオブジェクトを保存する
#include <iostream>
#include <vector>
using namespace std;
class Demo {
double d;
public:
Demo() { d = 0.0; }
Demo(double x) { d = x; }
double getd() { return d; }
};
int main()
{
vector<Demo> v;
int i;
for(i=0; i<10; i++)
v.push_back(Demo(i/3.0));
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
for(i=0; i<v.size(); i++)
v[i] = v[i].getd() * 2.1;
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
return 0;
}
オフトピック
i<v.size()のところで、comparison between signed and unsigned integer expressionsっていう警告が出るなあ。
Re: 演算子多重定義が必要な理由
Posted: 2015年8月14日(金) 14:25
by みけCAT
この場合見かけの動作は変わらないですが、代入演算子のオーバーロードがあるときと無いときでは内部の動作が異なります。
どの関数が呼ばれたかをわかるようにすると、違いがわかります。
ちなみに比較演算子2個は、このコードでは全く動作に関係無いようですね。
オーバーロードあり
コード:
// ベクトルにクラスオブジェクトを保存する
#include <iostream>
#include <vector>
using namespace std;
class Demo {
double d;
public:
Demo() { d = 0.0; }
Demo(double x) {
cout << "constructed : " << x << endl;
d = x;
}
Demo &operator=(double x) {
cout << "assigned : " << x << endl;
d = x; return *this;
}
double getd() { return d; }
};
bool operator<(Demo a, Demo b)
{
cout << "lt? " << a.getd() << " and " << b.getd() << endl;
return a.getd() < b.getd();
}
bool operator==(Demo a, Demo b)
{
cout << "equal? " << a.getd() << " and " << b.getd() << endl;
return a.getd() == b.getd();
}
int main()
{
vector<Demo> v;
int i;
for(i=0; i<10; i++)
v.push_back(Demo(i/3.0));
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
for(i=0; i<v.size(); i++)
v[i] = v[i].getd() * 2.1;
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
return 0;
}
実行結果
コード:
constructed : 0
constructed : 0.333333
constructed : 0.666667
constructed : 1
constructed : 1.33333
constructed : 1.66667
constructed : 2
constructed : 2.33333
constructed : 2.66667
constructed : 3
0 0.333333 0.666667 1 1.33333 1.66667 2 2.33333 2.66667 3
assigned : 0
assigned : 0.7
assigned : 1.4
assigned : 2.1
assigned : 2.8
assigned : 3.5
assigned : 4.2
assigned : 4.9
assigned : 5.6
assigned : 6.3
0 0.7 1.4 2.1 2.8 3.5 4.2 4.9 5.6 6.3
オーバーロードなし
コード:
// ベクトルにクラスオブジェクトを保存する
#include <iostream>
#include <vector>
using namespace std;
class Demo {
double d;
public:
Demo() { d = 0.0; }
Demo(double x) {
cout << "constructed : " << x << endl;
d = x;
}
double getd() { return d; }
};
int main()
{
vector<Demo> v;
int i;
for(i=0; i<10; i++)
v.push_back(Demo(i/3.0));
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
for(i=0; i<v.size(); i++)
v[i] = v[i].getd() * 2.1;
for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";
cout << endl;
return 0;
}
実行結果
コード:
constructed : 0
constructed : 0.333333
constructed : 0.666667
constructed : 1
constructed : 1.33333
constructed : 1.66667
constructed : 2
constructed : 2.33333
constructed : 2.66667
constructed : 3
0 0.333333 0.666667 1 1.33333 1.66667 2 2.33333 2.66667 3
constructed : 0
constructed : 0.7
constructed : 1.4
constructed : 2.1
constructed : 2.8
constructed : 3.5
constructed : 4.2
constructed : 4.9
constructed : 5.6
constructed : 6.3
0 0.7 1.4 2.1 2.8 3.5 4.2 4.9 5.6 6.3