[一道搜狗输入法的面试题]C++转换构造函数和类型转换函数
今天面試遇到一道有關C++轉換構造函數的題目,之前經常見到默認構造函數、拷貝構造函數、析構函數,但是從沒聽說過轉換構造函數,隱式轉換函數也是一樣,C++的確是夠博大精深的,學習之路很長啊!
其實我們已經在C/C++中見到過多次標準類型數據間的轉換方式了,這種形式用于在程序中將一種指定的數據轉換成另一指定的類型,也即是強制轉換,比如:int a = int(1.23)(C++形式)或者int a = (int)1.23(C形式)其作用是將1.23轉換為整形1。然而對于用戶自定義的類類型,編譯系統并不知道如何進行轉換,所以需要定義專門的函數來告訴編譯系統改如何轉換,這就是轉換構造函數和類型轉換函數!
一、轉換構造函數
轉換構造函數(conversion constructor function) 的作用是將一個其他類型的數據轉換成一個類的對象。
當一個構造函數只有一個參數,而且該參數又不是本類的const引用時,這種構造函數稱為轉換構造函數。
轉換構造函數是對構造函數的重載。
例如:
Complex(double r) { real=r; imag=0; }其作用是將double型的參數r轉換成Complex類的對象,將r作為復數的實部,虛部為0。用戶可以根據需要定義轉換構造函數,在函數體中告訴編譯系統怎樣去進行轉換。
那么如何利用轉換構造函數,進行自定義類型轉換呢?看下面的例子:
#include <iostream> using namespace std; class Complex { public:Complex():real(0),imag(0){cout << "Default ctor..." << endl;}Complex(double r, double i):real(r), imag(i){cout << "Param ctor..." << endl;}Complex(double r):real(r),imag(0){cout << "Convert ctor..." << endl;} Complex(const Complex& c1){cout << "Copy ctor..." << endl;this->real = c1.real;this->imag = c1.imag;}Complex& operator=(const Complex& c1){cout << "Assign ctor..." << endl;this->real = c1.real;this->imag = c1.imag;return *this;}Complex operator+(const Complex& c){return Complex(this->real + c.real, this->imag + c.imag);}void Print(){cout << "real = " << real << " imag = " << imag << endl;}private:double real, imag; }; int main() { Complex c;c = 1.2;c.Print();Complex c1(2.9, 4.2);Complex c2 = c1 + 3.1;c2.Print();return 0; }結果輸出為:
注:編譯器是不會自動的添加轉換構造函數的,因為它不知道怎么轉換。
二、類型轉換函數
用轉換構造函數可以將一個指定類型的數據轉換為類的對象。但是不能反過來將一個類的對象轉換為一個其他類型的數據(例如將一個Complex類對象轉換成double類型數據)。而類型轉換函數就是專門用來解決這個問題的!
類型轉換函數的作用是將一個類的對象轉換成另一類型的數據。
如果已聲明了一個Complex類,可以在Complex類中這樣定義類型轉換函數:
類型轉換函數的一般形式為:
operator 類型名( ) {實現轉換的語句 }注意事項:
1.在函數名前面不能指定函數類型,函數沒有參數。
2.其返回值的類型是由函數名中指定的類型名來確定的。
3.類型轉換函數只能作為成員函數,因為轉換的主體是本類的對象,不能作為友元函數或普通函數。
4.從函數形式可以看到,它與運算符重載函數相似,都是用關鍵字operator開頭,只是被重載的是類型名。double類型經過重載后,除了原有的含義外,還獲得新的含義(將一個Complex類對象轉換為double類型數據,并指定了轉換方法)。這樣,編譯系統不僅能識別原有的double型數據,而且還會把Complex類對象作為double型數據處理。
看下面的代碼:
#include <iostream> using namespace std; class Complex { public:Complex():real(0),imag(0){cout << "Default ctor..." << endl;}Complex(double r, double i):real(r), imag(i){cout << "Param ctor..." << endl;}//轉換構造函數Complex(double r):real(r),imag(0){cout << "Convert ctor..." << endl;} //重載+運算符Complex operator+(const Complex& c){return Complex(this->real + c.real, this->imag + c.imag);}//類型轉換函數operator double(){return real;}private:double real, imag; }; int main() { Complex c1(1.2, 2.3); double d; d = c1 + 1.1; // 調用類型轉換函數將c1轉換為double cout<<d<<endl; return 0; }代碼是不能通過編譯的:
error C2666: '+' : 2 overloads have similar conversions也就是說我們在這里定義了轉換構造函數和轉換函數,編譯器不知道c1+1.1應該調用哪一個。到底是把c1轉換成double,還是把1.1轉換成對象,產生二義性。
這里的解決辦法就是,把轉換構造函數去掉。但是如果把類型轉換函數去掉,那么最后在把對象轉換成double的時候還是通不過編譯。
總結:轉換構造函數和類型轉換函數就是在做自定義的類型同其它數據類型直接的方便的轉換。(通過賦值符號=直接轉換)
?
轉載于:https://www.cnblogs.com/stemon/p/4836611.html
總結
以上是生活随笔為你收集整理的[一道搜狗输入法的面试题]C++转换构造函数和类型转换函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 历史最牛 多页切换TabHost,给大家
- 下一篇: Node.js实践第一天