在〈運算子重載〉,若 Rational
加法的左運算元是 int
整數的話,運算子重載時使用了 friend
非成員函式,這明確地定義了遇到 int
為左運算元,而右運算元為 Rational
,計算結果要是 Rational
的話,應該採取的行為。
然而,在其他的運算需求中,可能會想要 Rational
能轉換為 int
、double
或者是其他型態,以便進一步以該型態的其他值進行運算,這可以透過自訂轉換函式來達到,又稱為轉型運算子。例如:
#include <iostream>
#include <string>
using namespace std;
struct Double {
const double n;
Double(double n) : n(n) {}
};
class Rational {
int numer;
int denom;
public:
Rational(int numer, int denom) : numer(numer), denom(denom) {}
operator double() {
return static_cast<double>(this->numer) / this->denom;
}
operator Double() {
return Double(static_cast<double>(this->numer) / this->denom);
}
};
void foo(Double d) {
cout << d.n << endl;
}
int main() {
Rational a(1, 2);
// a 隱含地轉換為 double
cout << a + 0.1 << endl;
cout << 0.3 + a << endl;
// a 隱含地轉換為 Double
foo(a);
return 0;
}
以上的範例,允許編譯器隱含地完成型態轉換,如果型態轉換必須得明確,可以加上 explicit
,例如:
#include <iostream>
#include <string>
using namespace std;
struct Double {
const double n;
explicit Double(double n) : n(n) {}
};
class Rational {
int numer;
int denom;
public:
Rational(int numer, int denom) : numer(numer), denom(denom) {}
explicit operator double() {
return static_cast<double>(this->numer) / this->denom;
}
explicit operator Double() {
return Double(static_cast<double>(this->numer) / this->denom);
}
};
void foo(Double d) {
cout << d.n << endl;
}
int main() {
Rational a(1, 2);
cout << static_cast<double>(a) + 0.1 << endl;
cout << 0.3 + static_cast<double>(a) << endl;
foo(static_cast<Double>(a));
return 0;
}
將範例中的 static_cast
拿掉,就會發生編譯錯誤,因為 explicit
指出不允許隱含型態轉換。