2016-07-06 9 views
3
#include <iostream> 
#include <cmath> 

using namespace std; 

class Complex 
{ 
private: 
    double real; 
    double imag; 

public: 
    // Default constructor 
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) 
    {} 

    // magnitude : usual function style 
    double mag() 
    { 
     return getMag(); 
    } 

    // magnitude : conversion operator 
    operator int() 
    { 
     return getMag(); 
    } 

private: 
    // class helper to get magnitude 
    double getMag() 
    { 
     return sqrt(real * real + imag * imag); 
    } 
}; 

int main() 
{ 
    // a Complex object 
    Complex com(3.0, 4.0); 

    // print magnitude 
    cout << com.mag() << endl; 
    // same can be done like this 
    cout << com << endl; 
} 

cout << com << endl;の変換演算子をコンパイラが呼び出す方法を理解できません。変換演算子を使用しているクラスオブジェクト

同じクラスに複数の変換演算子を含めることもできます。その場合、決議はどのように行われるのですか?

+0

を*「私は、コンパイラがどのように理解していませんcout << com << endl;」の変換演算子を呼び出すことを決意する*他に何をすると思いますか? –

+0

標準のヘッダーの 'cout'を調べることができます。そして、それが一致するまでこれらのそれぞれをチェックすることに気付く。あなたのクラスが提供するもの。 –

+3

_ "複数の変換演算子を持つこともできます" _コンパイラは "あいまいさ"エラーを出します(単一の変換が "最高"とみなされない場合) – mvidelgauz

答えて

9

変換演算子をintと宣言しました。この演算子は明示的ではないため、コンパイラはostream::operator<<の最適オーバーロードを検出したときにそれを考慮します。 C++コンパイラは常に、変換コンストラクタ、変換演算子、暗黙の型変換など、一致する呼び出しを見つけるために型を自動的に変換しようとします。同じようにしている複数の変換がある場合は、あなたの質問の後半部分に関しては

explicit operator int() { 
    return getMag(); 
} 

:あなたはexplicitとしてオペレータをマークすることができ、その後C++ 11から始まる、この動作を望まない場合は

良い、コンパイルエラーが呼び出されます。 operator doubleを追加した場合は、ostream::operator(double)が存在するため、呼び出しが不明瞭になり、希望のタイプにcomをキャストする必要があります。

+0

コンパイル時に、 inbuiltデータ型、 'int'、' float'、 'char'などに変換演算子を変換します。変換演算子を別のクラスのオブジェクトに変換するとどうなりますか?それはエラーをスローしますか? –

+1

@InsaneCoder私が言ったように、ヘッダー 'iostream'を読んで、どのタイプが' cout'のための変換を定義しているのか見てみてはどうでしょうか? –

+2

@InsaneCoderいいえ、「組み込みデータ型」への変換は検索されません。他のオーバーロード解決法と同様に、それは知っている 'operator <<'のすべての宣言を集め、2つの引数( 'std :: cout'と' com')をそのパラメータ型に変換しようとします。それがちょうど1つの場合に成功すれば、それはそれを使用します。つまり、文字列ストリーミング演算子が表示されている場合など、 'std :: string'への変換を試すこともできます。 – Angew

0

私は、コンパイラがcoutに過負荷が定義されている型に変換しようとします。 coutに過負荷が定義されている2つのタイプに変換できる場合は、コンパイルエラーが発生します。あなたがクラスコードにこの機能を追加した場合 はコンパイルされません。

// magnitude : conversion operator 
operator float() 
{ 
    return getMag() + 1; 
} 

をあなたがそのようなキャストしなければならないことを解決するために:

// same can be done like this 
cout << "Com: " << (float) com << endl; 
+0

はい、私は認めましたが、 "coutに過負荷が定義されているタイプ"が良い定義です。私は私の答えを編集します。 – JMA

関連する問題