面试中的C++问题(1)
虽然大部分面试都是问项目,然后一道代码题,但还是有少量公司很喜欢问“基础的”技术问题,比如C++、体系结构之类。因此开个新系列,记录一下面试里遇到的一些技术类问题。有一些很简单,也有一些可能也没那么常见。
explicit
很基础的问题,用于避免隐式类型转换。遇到过的一个坑是图形学光线追踪大作业的框架,里面Color
类构造函数RGB三个值都给了默认值然后没加explicit
,导致3.0f * Color(...)
时会把3.0f
隐式转化成Color
...
数组初始化默认值
1 | int a[8] = {1, 2, 3}; |
那么没有显式写出来的值都是0.
char
类型转换
1 | char a = -1; |
问b > 0
是否成立。显然不成立,char
是有符号的。
0
, NULL
, nullptr
这个问题没有那么显然。在C里,NULL
定义为
1 |
因此NULL
在C中可以安全地当成空指针使用。
但C++没那么轻松,因为C++不允许void *
隐式转换成其他类型的指针,所以不能沿用C的做法;只能简单地定义为0:
1 |
但C++支持同名函数重载,如果一个函数定义为
1 | void func(int a); |
那么func(NULL)
就会导致二义性问题:预期调用指针版本的函数,但实际上参数为整形,调用了整形版本的函数。
为了解决这个问题,C++ 11引入了空指针字面量nullptr
,其类型为std::nullptr_t
,可以隐式类型转换为任意类型指针或类成员指针。在一些C++ 11之后的实现中,NULL
定义为nullptr
。
延伸:类成员指针不是指针
类成员指针实际上是偏置量offset,而不是指向某一内存地址的指针。参考:Pointers to Member Functions.
如何在执行main
函数前做一些自定义行为?
一个trick:
1 |
|
全局变量在main
之前初始化,因此只要在自定义类型的构造函数里安排自定义行为,然后定义一个全局变量对象即可。
一个想法:或许这里用
static Foo foo;
更好。
模板函数能否在.cpp
里实现,编译后成.o
后再链接?
不行。本科写图形学大作业时踩过的坑,当时乔总就告诉我应该直接写在.hpp
头文件里。
原理是template
并没有定义任何东西,只有特化后确定了类型信息,编译器才能分配空间进而编译成.o
,否则无法编译。
延伸:避免模板重复
据说可以用extern
,没有尝试过。