某日二师兄参加XXX科技公司的C++工程师开发岗位第20面:

面试官:C++中支持哪些类型转换?

二师兄:C++支持C风格的类型转换,并在C++11引入新的关键字规范了类型转换。

二师兄:C++11引入四种新的类型转换,分别是static_castdynamic_castconst_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为什么还要引入新的类型转换关键字?

二师兄:主要有三点,更安全、更灵活、可读性更好。

面试官:知道什么是隐式转换吗?

二师兄:了解一些。隐式转换是指在表达式中自动进行的类型转换。比如intdouble相加,会把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了解一下?的更多相关文章

  1. 《面试八股文》之kafka21卷

    微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是moon,最新一篇面试八股文系 ...

  2. 《面试八股文》之 Redis 16卷

    微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是 moon. redis 作为 ...

  3. 《面试八股文》之 JVM 20卷

    微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是 moon. <面试八股 ...

  4. 这可能是最全面的TCP面试八股文了

    计算机网络基础,考验一个程序员的基本功,也能更快的筛选出更优秀的人才. 说说TCP的三次握手 假设发送端为客户端,接收端为服务端.开始时客户端和服务端的状态都是CLOSED. 第一次握手:客户端向服务 ...

  5. 一天吃透MySQL面试八股文

    什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据.你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列).行代表每一行数据,列代表该行中的每个值.列上的值是 ...

  6. 一天吃透JVM面试八股文

    什么是JVM? JVM,全称Java Virtual Machine(Java虚拟机),是通过在实际的计算机上仿真模拟各种计算机功能来实现的.由一套字节码指令集.一组寄存器.一个栈.一个垃圾回收堆和一 ...

  7. 这可能是最全面的MySQL面试八股文了

    什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据.你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列).行代表每一行数据,列代表该行中的每个值.列上的值是 ...

  8. 这可能是最全面的Redis面试八股文了

    Redis连环40问,绝对够全! Redis是什么? Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库.与传统数据库不同的是,Re ...

  9. 三天吃透Spring面试八股文(最新整理)

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...

  10. 三天吃透Java虚拟机面试八股文

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...

随机推荐

  1. Junit环境配置和在IDEA中使用Junit学习记录

    Junit环境配置 步骤1:检查电脑中Java环境是否配置成功 因为JUnit 是 Java 的一个框架,所以最根本的需要是在你的机器里装有 JDK. 1.1 进入cmd控制台界面,输入java/ja ...

  2. Excel或数据库快速生成GUID

    一般一些开发软件或者网站可以直接生成guid, 比如:https://www.iamwawa.cn/guid.html 但是在某些场景下,经常在一些excel或者数据库操作需要快速生成指定格式的gui ...

  3. kubernetes(k8s)中部署 efk

    Kubernetes 开发了一个 Elasticsearch 附加组件来实现集群的日志管理.这是一个 Elasticsearch.Fluentd 和 Kibana 的组合. Elasticsearch ...

  4. 浅析Nordic nRF5 SDK例程架构

    很多刚接触Nordic nRF5 SDK的初学者出于对新平台的不熟悉,会觉得这个SDK很难,本文讲浅析nRF5 SDK中例程的架构,让初学者能够快速上手SDK. 在开始之前,先推荐阅读观看下面这些文章 ...

  5. 基于SpringBoot实现单元测试的多种情境/方法(二)

    本文分享自天翼云开发者社区@<基于SpringBoot实现单元测试的多种情境/方法(二)>,  作者:才开始学技术的小白 1 Mock基础回顾 在上一篇分享中我们详细介绍了简单的.用moc ...

  6. asyncio的基本使用框架,python高效处理数据,asyncio.gather(),asyncio. create_task(),asyncio.run(main())

    asyncio 是 Python 3.4 引入的标准库,是一个基于事件循环的异步 I/O 并发库.它提供了一种协作式的多任务处理方式,使得我们能够在一个线程中并发处理多个 I/O 操作.它通过将 I/ ...

  7. 分享一个提高运维效率的 Python 脚本

    哈喽大家好我是咸鱼,今天给大家分享一个能够提升运维效率的 python 脚本 咸鱼平常在工作当中通常会接触到下面类似的场景: 容灾切换的时候批量对机器上的配置文件内容进行修改替换 对机器批量替换某个文 ...

  8. Vue拖拽排序

    转载至https://www.crazyming.com/note/757/ 使用拖拽功能来实现排序. 需要先学习w3cschool 关于拖拽的教程:http://www.w3school.com.c ...

  9. 文心一言 VS chatgpt (10)-- 算法导论 3.1 2~3题

    二.证明:对任意实常量a和b,其中b>0,有(n+a) ^ b=O(n ^ b). 文心一言: 设a=b,则有(n+a) ^ b=(n+b)(n+a)=n ^ b+n ^ b =O(n ^ b) ...

  10. 2022-10-29:go语言中的defer能非常方便地处理资源释放问题,rust语言里如何实现defer功能呢?

    2022-10-29:go语言中的defer能非常方便地处理资源释放问题,rust语言里如何实现defer功能呢? 答案2022-10-29: rust里有时候你也必须用defer,别说是设计上的问题 ...