2017-06-23 23 views
0

我只是嘗試幾個代碼來理解超載< <運算符,大多數解釋都是很容易理解的,但我正在面對使用const關鍵字的一些問題。 下面的代碼是給我一個編譯錯誤,他說敵不過操作數分數,分數)影響不使用常量,而重載*運算符

#include<iostream> 
using namespace std; 
class Fraction 
{ 
private: 
    int m_numerator; 
    int m_denominator; 
public : 
    Fraction(int val1, int val2):m_numerator(val1),m_denominator(val2){}; 
    void print() 
    { 
     cout<<m_numerator<<"/"<<m_denominator<<endl; 
    } 
    friend Fraction operator*(Fraction &f1,Fraction &f2); 
    friend Fraction operator*(Fraction &f1, int value); 
    friend Fraction operator*(int value,Fraction &f1); 
}; 

Fraction operator*(Fraction &f1,Fraction &f2) 
{ 
    return Fraction(f1.m_numerator * f2.m_numerator, f1.m_denominator * f2.m_denominator); 
} 

Fraction operator*(Fraction &f1, int value) 
{ 
    return Fraction(f1.m_numerator * value, f1.m_denominator); 
} 

Fraction operator*(int value,Fraction &f1) 
{ 
    return Fraction(f1.m_numerator * value, f1.m_denominator); 
} 

int main() 
{ 
Fraction f1(2, 5); 
f1.print(); 

Fraction f2(3, 8); 
f2.print(); 

Fraction f3 = f1 * f2; 
f3.print(); 

Fraction f4 = f1 * 2; 
f4.print(); 

Fraction f5 = 2 * f2; 
f5.print(); 

Fraction f6 = Fraction(1, 2) * Fraction(2, 3) * Fraction(3, 4); 
f6.print(); 
} 

與上面的代碼的問題是,有沒有const的前面有一個Fraction對象,而使用它作爲函數參數,下面的代碼工作正常:

#include<iostream> 
using namespace std; 
class Fraction 
{ 
private: 
    int m_numerator; 
    int m_denominator; 
public : 
    Fraction(int val1, int val2):m_numerator(val1),m_denominator(val2){}; 
    void print() 
    { 
     cout<<m_numerator<<"/"<<m_denominator<<endl; 
    } 
    friend Fraction operator*(const Fraction &f1,const Fraction &f2); 
    friend Fraction operator*(const Fraction &f1, int value); 
    friend Fraction operator*(int value,const Fraction &f1); 
}; 

Fraction operator*(const Fraction &f1,const Fraction &f2) 
{ 
    return Fraction(f1.m_numerator * f2.m_numerator, f1.m_denominator * f2.m_denominator); 
} 

Fraction operator*(const Fraction &f1, int value) 
{ 
    return Fraction(f1.m_numerator * value, f1.m_denominator); 
} 

Fraction operator*(int value,const Fraction &f1) 
{ 
    return Fraction(f1.m_numerator * value, f1.m_denominator); 
} 

int main() 
{ 
Fraction f1(2, 5); 
f1.print(); 

Fraction f2(3, 8); 
f2.print(); 

Fraction f3 = f1 * f2; 
f3.print(); 

Fraction f4 = f1 * 2; 
f4.print(); 

Fraction f5 = 2 * f2; 
f5.print(); 

Fraction f6 = Fraction(1, 2) * Fraction(2, 3) * Fraction(3, 4); 
f6.print(); 
} 

爲什麼常量在這裏打這麼多重要的角色,可以有場景,其中,我不需要const關鍵字,我怎麼去處理這些案件。 PS:錯誤在特定行中: 分數f6 =分數(1,2)*分數(2,3)*分數(3,4);分數

任何解釋將是一個很大的幫助。

+0

這是一個錯誤,我剛剛編輯了這個問題。謝謝 – user3530616

回答

0

失敗的線是這個:

Fraction f6 = Fraction(1, 2) * Fraction(2, 3) * Fraction(3, 4); 

的原因是匿名臨時對象不能被修改。這是一種語言功能,旨在保護您免受自己的傷害,因爲通常情況下,如果您想修改某些要使用結果的內容。所以你的非修改操作符需要通過const-ref或value來接受它們的參數。

+1

我認爲他們*可以被修改(人們用來返回常量值的原因之一)。它們不能綁定到非常量左值引用。 – juanchopanza

0

您確實需要獲得const的正確性。所有的函數都會告訴編譯器它們可以修改傳入的參數。

具體而言,這意味着這樣的:

Fraction f6 = Fraction(1, 2) * Fraction(2, 3) * Fraction(3, 4); 

其編譯器產生的代碼是這樣的:

Fraction const tmp1 = Fraction(1, 2); 
Fraction const tmp2 = Fraction(2, 3); 
Fraction const tmp3 = operator*(tmp1, tmp2); 
Fraction const tmp4 = Fraction(3, 4); 
Fraction f6 = operator*(tmp3, tmp4); 

需要注意的是編譯器產生的臨時實際上不是const,但你不能綁定給他們使用非const引用(即你應該在函數原型中使用const &而不是僅僅使用&,或者根本不使用引用),部分原因是因爲如果你編寫改變tempor的代碼隨後消失的ary,這是非常沒有意義的,幾乎毫無疑問不是你想要做的。 (歷史記錄:至少有一個fortran IV編譯器的版本 - 其中所有內容都是由非const引用傳遞的),可以更改數值常量1的值,因爲該語言沒有常量或臨時變量的概念,導致很混亂)。

但是,您的算術運算符都沒有采用const引用(儘管實際上並未改變它們的參數),但編譯器找不到適當的方法來使用,因此會錯誤地使用該語句。

順便說一下,您沒有運算符重載,並且在代碼示例中沒有任何地方會實際使用它,如果有的話。

另請注意,您的print方法不是const,它應該是或者您不會在const Fraction對象上使用它。

+0

非常感謝......請你解釋一下這個問題,「但是你只能用非const引用來綁定它們......」 – user3530616

+0

對不起,錯字較早。清理並擴大 –

+0

謝謝......它幫助.. !! – user3530616