設計一個有理數類別 Rational,需支援與 double 的乘法運算:
Rational = Rational * doubleRational = double * Rational若乘法實作為成員函數,左運算元必須是 Rational 物件。當出現 double * Rational 時,編譯器找不到合適的成員函數,導致編譯失敗。
將 operator* 實作為非成員函數(可宣告為 friend),並利用 Rational 的建構函數隱式轉換 double:
class Rational {
public:
Rational(double numerator = 0, double denominator = 1)
: m_n(numerator), m_d(denominator) {}
double numerator() const { return m_n; }
double denominator() const { return m_d; }
double value() const { return m_n / m_d; }
private:
double m_n, m_d;
};
// 非成員函數,支援雙向運算
const Rational operator*(const Rational& lhs, const Rational& rhs) {
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}
oneFourth * 3.5 → 3.5 隱式轉換為 Rational(3.5) → 呼叫 operator*(Rational, Rational)。3.5 * oneFourth → 3.5 隱式轉換為 Rational(3.5) → 呼叫同一個 operator*。#include <iostream>
class Rational {
public:
Rational(double numerator = 0, double denominator = 1)
: m_n(numerator), m_d(denominator) {}
double numerator() const { return m_n; }
double denominator() const { return m_d; }
double value() const { return m_n / m_d; }
private:
double m_n, m_d;
};
const Rational operator*(const Rational& lhs, const Rational& rhs) {
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}
int main() {
Rational oneFourth(1, 4);
Rational result;
result = oneFourth * 3.5;
result = 3.5 * oneFourth;
std::cout << "result = " << result.value() << std::endl; // 0.875
return 0;
}
「如果所有參數都需要型別轉換,該函數應為非成員函數。」
這樣才能支援左運算元為內建型別(如 double、int)的情況,確保介面對稱、直觀且易用。