演算子のリロードにおける暗黙的な変換の問題

2560 ワード

問題の説明:
譚浩強c++本の中の演算子は暗黙的に以下の2つの言葉の問題friend Complex operator+(Complex&,Complex&);friend Complex operator+(const Complex&,const Complex &);
知識点:
1.暗黙変換はconst以外の参照パラメータには使用されない.二義性問題3.なぜ友元関数を使うのか
詳細:
#include
#include
using namespace std;
class Complex
{
public:
	Complex(){ real = 0; imag = 0; }
	Complex(float r){ real = r; imag = 0; }//       
	Complex(float r, float i) :real(r), imag(i){}
	friend Complex operator+(Complex&, Complex&);//       
	operator double() const { return real; } //     ,       ,      ,,             ,     const
        //friend Complex operator+(const Complex&,const Complex &)//               ,          
	void display();
private:
	float real;
	float imag;
};
void Complex::display()
{
	cout << "(" << real;
	if (imag >= 0)cout << ",";
	else cout << ",";
	cout << imag << "i)" << endl;
}
Complex operator+(Complex &c1, Complex  &c2)
{
	return Complex(c1.real , c1.imag + c2.imag);
}
int main()
{
	Complex c1(3, 5), c3;
	float i = 5;
	c3 = i + c1;
	c3.display();
	return 0;
}



1.暗黙変換はconst以外の参照パラメータには使用されません
非constの参照は同じタイプのオブジェクトのみをバインドできるため、constは互いに変換できるタイプをバインドできます.すなわち、暗黙的な変換はconst以外の参照パラメータには使用されません.
2.二義的な問題
1)上記のコードが非const参照である場合、iはdoubleタイプであり、演算子リロード関数を呼び出すには、iがComplexタイプ参照に変換する必要があるため、一時変数が作成され、演算子リロード関数を呼び出すことができなくなるため、c 1がタイプ変換関数を呼び出し、c 1をdoubleタイプにし、2つのdoubleタイプが加算される.変換コンストラクタを呼び出し、右の値をComplexタイプ、プロセスをc 3にする.Complex((c 1.operator double(c 1)+i)には二義性はありません.
2)アノテーション行を使用し、パラメータがconst以外の参照である場合、二義性.1つ目は同じで、2つ目は、iをComplexタイプに変換してから、リロードされた+演算子を呼び出し、c 3に値を割り当て、operator+(c 1,temp.Complex(i))に二義性を見た.
3)他の場所で見た分かりやすくて、悪くないと思います.constリファレンスが入力されている場合、constは「変更されない」を表し、変更されず出力されないことに等しいため、入力文字配列は一時的な文字列に変換されてconstリファレンスを提供することができます.「変換されたこの一時変数は、関数が終了したときに直接破棄すればよいので、問題はありません.ただし、const参照でない場合は、「変更される」、つまり出力があることを意味します.文字配列は文字列に変換できますが、この一時文字列は関数が終了した後どうすればいいですか?破棄する意味がないと言っていますが、どうやってコンパイラに伝えますか?コンパイラが知らないと、それは間違っています.
3.なぜ友元関数を使うのか
「c++Primer中国語版第4版」はp 435ページで指導原則があり、こう述べた.
IOオペレータは非メンバー関数でなければなりません.このオペレータをクラスのメンバーとして定義することはできません.そうしないと、左オペレータはクラスタイプのオブジェクトのみになります.
下付きオペレータはメンバー関数でなければなりません.
演算オペレータ/等しいオペレータ/リレーショナルオペレータ/ビットオペレータなどの対称オペレータは、通常の非メンバー関数(友元)として定義することが望ましい.