C++知识点 面试常问考点

一、C++中包含哪几种强制类型转换,他们有什么联系和区别?

  1. reinterpret_cast:转换指针为其他类型的指针。操作结果知识简单的从一个指针到别的指针的二进制拷贝,在类型之间指向的内容不做任何类型的检查和转换。
    class A{};
    class B{};
    A* a = new A;
    B* b = reinterpret_cast(a);

     

  2. static_cast:允许执行任意的隐式转换和相反的转换。比如:应用到类指针上,允许子类类型的指针转换为父类类型的指针,同时,也允许转换父类为子类类型。
  3. dynamic_cast:只用于对象的指针和引用。dynamic_cast会检查操作是否有效。如果转换的指针不是一个有效完整的对象,则返回NULL, 对于引用,则返回bad_cast异常
  4. const_cast:这个转换类型操纵传递对象的const属性,或者是设置或者是删除
    class C{};
    const C* a = new C;
    C *b = const_cast(a);

二、C++虚函数作用及底层实现原理

C++中虚函数使用虚函数表和虚函数指针表实现,虚函数表是一个类的虚函数的地址表,用于索引类本身以及父类的虚函数的地址。假如子类的虚函数重写了父类的虚函数,则对应在虚函数表中会把对应的虚函数替换为子类的虚函数地址;虚函数表指针存在于每个对象中(通常为了提高效率,会放在对象的开始地址处),它指向对象所在类的虚函数表的地址。多继承情况下,会存在多个虚函数表指针,分别对应不同基类的虚函数表。

三、一个对象访问普通成员函数和虚函数那个更快?

访问普通成员函数更快,因为普通成员函数的地址在编译阶段就已确定,因此访问时直接调用,而虚函数需要先在虚函数表中寻找虚函数所在的地址。

四、什么情况下,析构函数需要虚函数

在存在类继承并且析构函数中需要析构某些资源时需要使用虚函数。否则若使用父指针指向子类对象,在delete时只会调用父类的析构函数,而不能调用子类的析构函数,造成内存泄漏。

五、内联函数、构造函数、静态成员函数可以是虚函数吗?

都不可以。内联函数需要在编译阶段展开,而虚函数是运行时动态绑定的,编译时无法展开;构造函数在进行调用时还不存在父类和子类的概念,父类只会调用父类的构造函数,子类调用子类的,因此不存在动态绑定的概念;静态成员函数是以类为单位的函数,与具体对象无关,虚函数是与对象动态绑定的。

(动态绑定:动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。程序运行过程中,把函数(或过程)调用与响应调用所需要的代码相结合的过程称为动态绑定)

六、构造函数中可以调用虚函数吗?

可以,但是没有动态绑定的效果,父类构造函数中调用的仍是父类版本的函数,子类中调用的是子类版本的函数

七、C++中虚继承的作用和底层实现原理

虚继承用于解决继承条件下的菱形继承问题,底层实现原理与编译器有关,一般通过虚基类指针实现,即各对象中只保存一份父类的对象,多继承时通过虚基类指针引用该公共对象,从而避免菱形继承中的二义性问题

(菱形继承:A-------B    A-------C     B,C------D   B继承A,C继承A    D继承B,C,这样的话在D类中会出现两次A,为了节省内存空间,将B,C对A的继承定义为虚拟继承,A就成了虚拟基类

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值