[英]Overloading operator= or operator[] using const char* and/or string
[英]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.