類的自動轉換:
說明: C++允許程序員指定類之間進行轉換的方式(含基本類型)
站在類的角度看問題,姑且分爲“當前類” 和 “其他類”
假設: 當前類是程序員定義的,其他類既可以是程序員定義的,也可以是C++內置的基本類型
方式: 通過定義 “轉化函數”
1. 其他類轉換爲當前類
轉化函數:
本質: 允許只傳入一個實參的構造函數
包括:
1. 只接受一個參數的構造函數
2. 具有多個形參,但是在類的聲明中,存在一個參數沒有默認值,但是其他行參都有默認
值的構造函數
那麼,這裏的 “其他類” 指的就是那個在類聲明中沒有設置默認值的類型,或者能夠與這個類型自動轉換的類型
有了轉換函數之後呢,我們可以通過自動地將這個 “其他類” 的對象轉換爲 “當前類” 的對象
舉一個例子,實現了內置類型 int (“其他類”) 到Student類 (“當前類”) 的轉換
#include <iostream>
using namespace std;
class Student
{
private:
int id;
public:
Student() {
}
Student(int ID) {
id = ID;
}
};
int main() {
Student a = Student(1); //explicit
Student b(2); //explicit
Student c = 3; //implicit
return 0;
}
#include <iostream>
#include <string>
using namespace std;
class Student
{
private:
int id;
public:
Student() {
}
Student(int ID , string name="") {
id = ID;
}
};
int main() {
Student a = Student(1); //explicit
Student b(2.5); //explicit
Student c = 3.7; //implicit
return 0;
}
2. 當前類轉化爲其他類
“當前類” 轉化爲 “其他類” 就稍微麻煩點。因爲,它的 “轉換函數” 不是構造函數--需要額外定義
形式: operator typeName();
要求: 1. 成員函數
2. 不能指定返回類型 (即使如此,在實現時,你必須返回一個typeName類型的變量)
3. 不能有參數 (其實有一個默認的參數--指向當前對象的this指針)
一個例子
#include <iostream>
using namespace std;
class Student
{
private:
int id;
public:
Student() {
}
Student(int ID) {
id = ID;
}
operator int() {
return id;
}
};
int main() {
Student student(5);
cout << student << endl;
return 0;
}
在上面這段代碼中,含有語句 “cout << student << endl;”
爲什麼沒有爲 Student類 重載輸出操作符函數,而編譯器卻沒有報錯呢?
因爲,在輸出的時候,Student對象student被自動轉化爲int類型的變量。而身爲ostream對象的cout自然能處理int類型的變量
目前講到的,“當前類”轉換爲“其他類”的例子裏面,都是隱式類型轉換,我們可以通過使用強制類型轉換來使 “當前類” 轉換爲 “其他類”。
當然,在強制轉換之前,我們也要像上面一樣定義轉換函數。
強制類型轉換的句式我們也很熟悉了-- typeName (variable) 或 (typeName) variable
一些好的編程習慣:
1. 重載雙目運算符時,定義爲友元可以讓程序更容易適應自動類型轉換---兩個操作數都成爲了函數
參數,因此與函數原型匹配 (就是有轉換函數的意思)
因爲,如果操作數的類型不是當前類的類型,它可以通過 “轉換函數” 轉換爲當前類的對象,再調
用重載的運算符函數。
2. 自動轉換的隱式轉換,有時候會帶來一些難以發現的問題。爲了保險,可以使用顯式轉換,比如
通過 explicit 來限定轉換函數。
References:
[1]《C++ Primer Plus 6th Edition》