簡體   English   中英

重載*運算符時不使用const的影響

[英]Affect of not using const while overloading * operator

我只是在嘗試一些代碼來理解重載<<運算符,大多數解釋都是可以理解的,但是使用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();
}

上面的代碼的問題是,在將Fraction對象用作函數參數時,沒有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*(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在這里起着如此重要的作用,在某些情況下我不需要const關鍵字,我將如何處理這些情況。

PS:錯誤具體在行中:分數f6 =分數(1,2)*分數(2,3)*分數(3,4);

任何解釋都會有很大幫助。

失敗的行是這一行:

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

原因是匿名臨時者不能被修改。 這是一種語言功能,旨在保護您免受自己的傷害,因為通常如果您要修改某些內容,則可以使用結果。 因此,您的非修飾運算符需要通過const-ref或按值接受其參數。

您確實需要掌握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 &而不是just & ,或者根本不使用引用),部分原因是您編寫的代碼會更改一個臨時變量,該臨時變量隨后會消失,這毫無意義,幾乎毫無疑問不是您的本意。 (歷史記錄:在至少一個fortran IV編譯器的版本中-所有內容都由非const引用傳遞-可以更改數值常量1的值,因為該語言沒有常量性或臨時變量的概念,導致很多混亂)。

但是,您的算術運算符都沒有采用const引用(盡管實際上並未更改其參數),編譯器無法找到要使用的適當方法,因此會出錯。

順便說一句,您沒有operator <<重載,並且如果有一個,該代碼示例中的任何地方都不會實際使用它。

還要注意,您的print方法不是const ,應該是const ,否則您將無法在const Fraction對象上使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM