3

学校の課題のためにお金のクラスを作成しています。Moneyからdoubleへの変換を定義し、intを受け取るMoneyのコンストラクターがあり、別のコンストラクターがdoubleを取り、「+」演算子をオーバーロードして、Money型の2つのオブジェクトを足し合わせました。myMoney + 10myMoneyがMoney型のオブジェクトであり、10が明らかに整数であるようなことをしようとすると、エラーメッセージが表示されます。関連する残りのコードは次のとおりです。

class Money {
private:
    int dollars;
    int cents;
public:
    Money(double r);
    Money(int d) : dollars(d), cents(0) {}
    operator double();
}

Money operator+(Money a, Money b) {
    double r = double(a) + double(b);
    return Money(r);
}

Money::operator double() {
    return dollars+double(cents)/100;
}

Money::Money(double r) {
    ...
}

このプログラムは、試してみても、両方のコンストラクターを明示的にした場合でも実際に機能Money(double(myMoney)+10)しますが、それ以外の場合は自動変換で何が起こっているのかわかりません。誰かがこの振る舞いを説明できますか?

4

2 に答える 2

4
MyMoney + 10

がないためoperator+(Money, int)、ここでいくつかの変換を行う必要があります。コンパイラは、をに変換してMoneyからdouble、10を「double」に変換して組み込みを選択するoperator+(double,double)か、をに変換しintMoneyを選択することができますoperator+(Money,Money)

于 2012-04-27T00:31:16.153 に答える
0

コンパイラーによって見られ、Benjaminが指摘しているように、問題は、operator+オーバーロードに対する異なる有効な引数のセットにつながる2つの変換シーケンスがあることです。しかし、これは実際には設計に関するより深刻な問題を示しています。暗黙の変換はほとんど使用しないでください。2つの異なるタイプからの暗黙の変換を使用することは、問題のレシピです。

コンストラクターを明示的にし、変換演算子も明示的にする(C ++ 11言語機能)か、コンストラクターを削除して、の場合のように(演算子ではなくメンバー関数を介して)名前付き変換を提供することを検討してくださいstd::string::c_str()

何かが自動的にお金に変わることは本当に意味がありますか?そして、それは同じくらい簡単にほこりに変わりますか?型システムを弱める暗黙の変換を回避することにより、コンパイラーがロジックの問題を検出するのに役立つようにする方法を学びます。

于 2012-04-27T01:26:42.773 に答える