某日二师兄参加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
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(b1); //d1 == nullptr
Derived* d2 = dynamic_cast(b2); //d2 != nullptr
}
二师兄:
const_cast
主要用于去除指针或引用类型的const
属性。此操作可能会导致未定义的行为,所以需要慎用。
#include
void function(const int& val)
{
int& v = const_cast(val);
v = 42;
}
int main(int argc, char const *argv[])
{
int val = 1024;
function(val);
std::cout
static constexpr int val_static = 1024;
void function(const int& val)
{
int& v = const_cast(val);
v = 42;
}
int main(int argc, char const *argv[])
{
function(val_static);
std::cout
二师兄:
reinterpret_cast
可以将指针或引用转换为任何类型的指针或引用。reinterpret_cast
实现依赖于编译器和硬件,可能导致未定义的行为。
#include
int main(int argc, char const *argv[])
{
int i = 42;
double d = 42.0;
long* l1 = reinterpret_cast(&i);
long* l2 = reinterpret_cast(&d);
std::cout
面试官:好的。既然已经有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
struct Foo
{
Foo(double d):val_(d){}
double val_;
explicit operator int(){
return static_cast(val_);
}
};
int main(int argc, char const *argv[])
{
Foo f(42.5);
int i = static_cast(f);
std::cout
面试官:好的,回去等消息吧。
今天二师兄表现棒极了,晚上必须加个鸡腿。感谢小伙伴的耐心阅读。二师兄的C++面试之旅,明天继续。
关注我,带你21天“精通”C++!(狗头)
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net