某日二師兄參加XXX科技公司的C++工程師開發崗位第20面:
面試官:C++中支持哪些型別轉換?
二師兄:C++支持C風格的型別轉換,并在C++11引入新的關鍵字規范了型別轉換,
二師兄:C++11引入四種新的型別轉換,分別是
static_cast、dynamic_cast、const_cast、和reinterpret_cast,二師兄:
static_cast用途最廣泛,除了后面三種型別轉換外,其他的型別轉換都能使用static_cast完成,二師兄:
dynamic_cast主要用于運行時的從父類指標向子類指標轉換,如果轉換不成功則回傳nullptr,
#include <iostream>
struct Base
{
virtual void fun() {}
};
struct Derived : public Base
{
virtual void fun() override {}
};
int main(int argc, char const *argv[])
{
Base* b1 = new Base;
Base* b2 = new Derived;
Derived* d1 = dynamic_cast<Derived*>(b1); //d1 == nullptr
Derived* d2 = dynamic_cast<Derived*>(b2); //d2 != nullptr
}
二師兄:
const_cast主要用于去除指標或參考型別的const屬性,此操作可能會導致未定義的行為,所以需要慎用,
#include <iostream>
void function(const int& val)
{
int& v = const_cast<int&>(val);
v = 42;
}
int main(int argc, char const *argv[])
{
int val = 1024;
function(val);
std::cout << val << std::endl; //val == 42
}
//-----------------------------------------------
#include <iostream>
static constexpr int val_static = 1024;
void function(const int& val)
{
int& v = const_cast<int&>(val);
v = 42;
}
int main(int argc, char const *argv[])
{
function(val_static);
std::cout << val_static << std::endl;
}
// Segmentation fault
二師兄:
reinterpret_cast可以將指標或參考轉換為任何型別的指標或參考,reinterpret_cast實作依賴于編譯器和硬體,可能導致未定義的行為,
#include <iostream>
int main(int argc, char const *argv[])
{
int i = 42;
double d = 42.0;
long* l1 = reinterpret_cast<long*>(&i);
long* l2 = reinterpret_cast<long*>(&d);
std::cout << *l1 << std::endl; //*i1 == 42
std::cout << *l2 << std::endl; //*i2 == 4631107791820423168 X86_64 GCC 11.3
}
面試官:好的,既然已經有C風格的型別轉換,C++11為什么還要引入新的型別轉換關鍵字?
二師兄:主要有三點,更安全、更靈活、可讀性更好,
面試官:知道什么是隱式轉換嗎?
二師兄:了解一些,隱式轉換是指在運算式中自動進行的型別轉換,比如
int和double相加,會把int先轉為double,然后再進行求和,面試官:隱式轉換有哪些優勢和缺陷?
二師兄:隱式轉換的優勢是代碼簡潔,但是有很大缺陷,有些情況隱式轉換的結果和程式員的意圖不一致,會導致難以發現的問題,所以在實際專案中一般會添加編譯選項
-Werror=conversion來禁止隱式轉換,面試官:那你知道
explicit關鍵字有什么作用嗎?二師兄:也是禁止隱式轉換的一個方式:
struct Foo
{
Foo(int i):val_(i){}
int val_;
};
struct Goo
{
explicit Goo(int i):val_(i){}
int val_;
};
void function1(Foo f){}
void function2(Goo g){}
int main(int argc, char const *argv[])
{
Foo f = 1024; //編譯通過,可以把int型別轉換成Foo
Goo g = 1024; //編譯失敗,不能把int型別轉換成Goo
function1(42); //編譯通過,可以把int型別轉換成Foo
function2(42); //編譯失敗,不能把int型別轉換成Goo
}
面試官:如何把一個自定義型別轉換成一個
int型別?二師兄:需要多載
operator int()運算子:
#include <iostream>
struct Foo
{
Foo(double d):val_(d){}
double val_;
explicit operator int(){
return static_cast<int>(val_);
}
};
int main(int argc, char const *argv[])
{
Foo f(42.5);
int i = static_cast<int>(f);
std::cout << i << std::endl; //i == 42
}
面試官:好的,回去等訊息吧,
今天二師兄表現棒極了,晚上必須加個雞腿,感謝小伙伴的耐心閱讀,二師兄的C++面試之旅,明天繼續,
關注我,帶你21天“精通”C++!(狗頭)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/555676.html
標籤:其他
下一篇:返回列表
