C++面试八股文:static_cast了解一下?
某日二师兄参加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++!(狗头)
C++面试八股文:static_cast了解一下?的更多相关文章
- 《面试八股文》之kafka21卷
微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是moon,最新一篇面试八股文系 ...
- 《面试八股文》之 Redis 16卷
微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是 moon. redis 作为 ...
- 《面试八股文》之 JVM 20卷
微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是 moon. <面试八股 ...
- 这可能是最全面的TCP面试八股文了
计算机网络基础,考验一个程序员的基本功,也能更快的筛选出更优秀的人才. 说说TCP的三次握手 假设发送端为客户端,接收端为服务端.开始时客户端和服务端的状态都是CLOSED. 第一次握手:客户端向服务 ...
- 一天吃透MySQL面试八股文
什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据.你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列).行代表每一行数据,列代表该行中的每个值.列上的值是 ...
- 一天吃透JVM面试八股文
什么是JVM? JVM,全称Java Virtual Machine(Java虚拟机),是通过在实际的计算机上仿真模拟各种计算机功能来实现的.由一套字节码指令集.一组寄存器.一个栈.一个垃圾回收堆和一 ...
- 这可能是最全面的MySQL面试八股文了
什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据.你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列).行代表每一行数据,列代表该行中的每个值.列上的值是 ...
- 这可能是最全面的Redis面试八股文了
Redis连环40问,绝对够全! Redis是什么? Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库.与传统数据库不同的是,Re ...
- 三天吃透Spring面试八股文(最新整理)
本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...
- 三天吃透Java虚拟机面试八股文
本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...
随机推荐
- Java面向对象--接口和多态
final 关键字 最终修饰符 可以修饰 类 方法 变量 被final修饰后不能被继承 重写 二次赋值 修饰类时 该类不可以被继承 修饰方法时 该方法不能被重写 修饰变量时, 该变量只能赋值一次, 不 ...
- python入门教程之二环境搭建
环境搭建 1python解释器 当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件. 由于整个Pyth ...
- abc294G
Upd G 看上好模板的样子, 果然是个模板题 好题 , 首先考虑这张图的 \(Euler \ Tour\), 简单点说, 就是dfs一遍, 把每个点入栈出栈顺序存起来, 举个例子· 2 1 2 2 ...
- Java设计模式 —— 适配器模式
9 适配器模式 9.1 结构型模式 结构型模式(Structural Pattern) 关注如何将现有类或对象组织在一起形成更强大的结构.结构型模式根据描述目标不同可以分为两种: 类结构型模式:关心类 ...
- day33:进程锁&事件&进程队列&进程间共享数据
目录 1.锁:Lock 2.信号量:Semaphone 3.事件:Event 4.进程队列:Queue 5.生产者和消费者模型 6.JoinableQueue 7.Manager:进程之间共享数据 锁 ...
- 执行计划display_cursor函数
问题描述:关于oracle查看真实的执行计划,使用select * from table(dbms_xplan.display_cursor(null,null));的方式来获取执行计划 参考文档:h ...
- C 语言版线程池
一.初始线程池 1.1 何为线程池? 我们先来打个比方,线程池就好像一个工具箱,我们每次需要拧螺丝的时候都要从工具箱里面取出一个螺丝刀来.有时候需要取出一个来拧,有时候螺丝多的时候需要多个人取出多个来 ...
- 已知n个数的入栈序列,求一共有多少种出栈序列 (卡特兰数)
已知\(n\)个数的入栈序列,求一共有多少种出栈序列 这个经典问题有两种解法. 解法一: 设\(f(x)\)为\(x\)个数入栈后,再全部出栈的序列数量 假设我们有\(4\)个数\(a,b,c,d\) ...
- 飞腾CPU FT-2000/4 uboot下PHY调试记录
飞腾爱好者技术交流群码公众号"乌拉大喵喵" 一.环境说明 板子是FT-2000/4的开发板: 固件版本: ft-2004c_u-boot-v2-Ver0.3_20211223100 ...
- Django 如何使用 Celery 完成异步任务或定时任务
以前版本的 Celery 需要一个单独的库(django-celery)才能与 Django 一起工作, 但从 Celery 3.1 开始,情况便不再如此,我们可以直接通过 Celery 库来完成在 ...