C++重載類型轉(zhuǎn)換操作符(type cast operator)
boost::ref和boost::cref使用了重載“類型轉(zhuǎn)換(type cast)”操作符來實(shí)現(xiàn)使用引用類型來替換模版參數(shù),本文就介紹一下這種操作符的重載方法。
函數(shù)原型
T1::operator T2() [const]; //T1的成員函數(shù),重載"(T2)a"操作符
1. 類型轉(zhuǎn)換重載函數(shù)的返回值是隱含的,并且不能顯示聲明,返回值是與轉(zhuǎn)換的類型相同的,即為上面原型中的T2。
2. 不能有參數(shù);
3. 支持繼承,可以為虛函數(shù);
4. 支持使用typedef定義的類型;
先通過一個(gè)簡單的例子來說明如何使用類型轉(zhuǎn)換重載
1 #include
2
3 class D {
4 public:
5 D(double d) : d_(d) {}
6
7 /* 重載“(int)D” */
8 operator int() const {
9 std::cout << "(int)d called!" << std::endl;
10 return static_cast(d_);
11 }
12
13 private:
14 double d_;
15 };
16
17 int add(int a, int b) {
18 return a + b;
19 }
20
21 int main() {
22 D d1 = 1.1;
23 D d2 = 2.2;
24 std::cout << add(d1, d2) << std::endl;
25
26 return 0;
27 }
28
29
在24行執(zhí)行add(d1,d2)函數(shù)時(shí)“(int)D”重載函數(shù)將被調(diào)用,程序運(yùn)行的輸出為:
(int)d called!
(int)d called!
3
類型轉(zhuǎn)換操作符 vs 類型轉(zhuǎn)換構(gòu)造函數(shù)(conversion constructor)
有時(shí)候使用conversion constructor就能實(shí)現(xiàn)類型轉(zhuǎn)換,這種方式效率更高而且也更直觀,下面舉例說明:
1 #include
2
3 class A
4 {
5 public:
6 A(int num = 0) : dat(num) {}
7
8 /* 重載"(int)a" */
9 operator int() { return dat; }
10
11 private:
12 int dat;
13 };
14
15
16 class X
17 {
18 public:
19 X(int num = 0) : dat(num) {}
20
21 /* 重載"(int)a" */
22 operator int() { return dat; }
23
24 /* 重載"(A)a" */
25 operator A() {
26 A temp = dat;
27 return temp;
28 }
29
30 private:
31 int dat;
32 };
33
34
35 int main()
36 {
37 X stuff = 37;
38 A more = 0;
39 int hold;
40
41 hold = stuff; // convert X::stuff to int
42 std::cout << hold << std::endl;
43
44 more = stuff; // convert X::stuff to A::more
45 std::cout << more << std::endl; // convert A::more to int
46
47 return 0;
48 }
49
上面這個(gè)程序中X類通過重載“operator A()”來實(shí)現(xiàn)將X類型對象轉(zhuǎn)換成A類型,這種方式需要先創(chuàng)建一個(gè)臨時(shí)A對象再用它去賦值目標(biāo)對象;更好的方式是為A類增加一個(gè)構(gòu)造函數(shù):
A(const X& rhs) : dat(rhs) {}
同時(shí),請注意上面程序的第45行more的類型在調(diào)用std::cout時(shí)被隱式地轉(zhuǎn)成了int!
一個(gè)簡單boost::ref實(shí)現(xiàn)
通過重載type cast operator,我們就可以自己實(shí)現(xiàn)一個(gè)簡版的boost::ref。
1 #include
2
3 template
4 class RefHolder
5 {
6 public:
7 RefHolder(T& ref) : ref_(ref) {}
8
9 /* 重載“(T&)A”操作符 */
10 operator T& () const {
11 return ref_;
12 }
13
14 private:
15 T& ref_;
16 };
17
18
19 template
20 inline RefHolder ByRef(T& t) {
21 return RefHolder(t);
22 }
23
24 int inc(int& num) {
25 num++;
26 return num;
27 }
28
29
30 int main() {
31 int n = 1;
32 std::cout << inc(ByRef(n)) << std::endl; //RefHolder被轉(zhuǎn)換成了"int&"類型
33
34 return 0;
35 }