综合面试题(下)

来源:互联网 发布:python 字符串截断 编辑:程序博客网 时间:2024/04/29 13:38
10.C++中包含哪几种强制类型转换?他们有什么区别和联系
reinterpret_cast: 转换一个指针为其它类型的指针。它也允许从一个指针转换为整数类型,反之亦 然. 这个操作符能够在非相关的类型之间转换. 操作结果只是简单的从一个指针到别的指针的值的 二进制拷贝. 在类型之间指向的内容不做任何类型的检查和转换? class A{}; class B{}; A* a = new A;B* b = reinterpret_cast(a); • static_cast: 允许执行任意的隐式转换和相反转换动作(即使它是不允许隐式的),例如:应用到类 的指针上, 意思是说它允许子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换), 同 时, 也能够执行相敏感词作: 转换父类为它的子类 class Base {}; class Derive:public Base{}; Base* a = new Base; Derive *b = static_cast(a); • dynamic_cast: 只用于对象的指针和引用. 当用于多态类型时,它允许任意的隐式类型转换以及相 反过程. 不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast 会检查操作是否有效. 也就是说, 它会检查转换是否会返回一个被请求的有效的完整对象。检测在 运行时进行. 如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL. 对于引用 类型,会抛出bad_cast异常 • const_cast: 这个转换类型操纵传递对象的const属性,或者是设置或者是移除,例如: class C{}; const C* a = new C; C *b = const_cast(a);(1static_cast:在功能上基本上与C风格的类型转换一样强大,含义也一样。它有功能上的限制。例如,你不能用static_cast像用C风格转换一样把struct转换成int类型或者把double类型转换成指针类型。另外,static_cast不能从表达式中去除const属性,因为另一个新的类型转换符const_cast有这样的功能。       可以静态决议出类型的转换可能性,即使是在继承体系中,即使包括了多重继承和虚继承,只要可以进行静态决议就可以转换成功     (2const_cast:用于类型转换掉表达式的constvolatile属性。通过使用const_cast,你向人们和编译器强调你通过类型转换想做的只是改变一些东西的constness或者volatieness属性。这个含义被编译器所约束。如果你试图使用const_cast来完成修改constness或者volatileness属性之外的事情,你的类型转换将被拒绝。     (3dynamic_cast:它被用于安全地沿着类的继承关系向下进行类型转换。这就是说,你能用dynamic_cast把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用,而且你能知道转换是否成功。失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常(当对引用进行类型转换时)。     (4reinterpret_cast:使用这个操作符的类型转换,其转换结果几乎都是执行期定义。因此,使用reinterpret_cast的代码很难移植。reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。
11.简述C++虚函数作用及底层实现原理!
要点是虚函数表和虚函数表指针的作用。C++中虚函数使用虚函数表和 虚函数表指针实现,虚函数表是一个类的虚函数的地址表,用于索引类本身以及父类的虚函数的地 址,假如子类的虚函数重写了父类的虚函数,则对应在虚函数表中会把对应的虚函数替换为子类的 虚函数的地址;虚函数表指针存在于每个对象中(通常出于效率考虑,会放在对象的开始地址处), 它指向对象所在类的虚函数表的地址;在多继承环境下,会存在多个虚函数表指针,分别指向对应 不同基类的虚函数表。
12.一个对象访问普通成员函数和虚函数哪个更快!?
首先看是否构成虚函数重写,如果不构成 则一样快 如果构成了虚函数重写,那就访问普通成员函数更快, 因为构成了虚函数重写在编译阶段就不能确定函数地址,需要在运行的时候在虚表里查找; 调用函数的真实地址。
13.在什么情况下,析构函数需要是虚函数?!
首先要明确:1.每个析构函数(不加 virtual) 只负责清除自己的成员。2.可能有基类指针,指向的确是派生类成员的情况。(这是很正常的),   那么当析构一个指向派生类成员的基类指针时,程序就不知道怎么办了。    所以要保证运行适当的析构函数,基类中的析构函数必须为虚析构。        基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。所以,将析构函数声明为虚函数是十分必要的。
14.内联函数、构造函数、静态成员函数可以是虚函数吗?!
内联函数是在编译阶段就展开的,而虚函数是在运行阶段动态绑定的,因此不可以构造函数本身就是为了明确初始化对象才产生的,而虚函数主要是为了不再完全理解细节 也能正常处理对象,另外虚函数是在不同的类型产生不同的动作,现在没有对象何谈动,所以不可以。静态函数不属于某一个对象,而是属于类的本身,而虚函数是属于对象的所以不支持;因为C++不支持友元函数的继承,对于没有继承特性的函数何来虚函数的说法?
15.构造函数中可以调用虚函数吗?!
不可以因为在构造函数和析构函数中,对象是不完整的,可能会发生未定义的行为。
16.简述C++中虚继承的作用及底层实现原理!
作用:为了解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。这样不仅就解决了二义性问题,也节省了内存,避免了数据不一致的问题。底层实现原理:底层实现原理与编译器相关,一般通过虚基类指针实现,即各对象中只保存一份父类的对象,多继承时通过虚基类指针引用该公共对象,从而避免菱形继承中的二义性问题。
原创粉丝点击