程序员面试宝典三
来源:互联网 发布:linux 使用ssr客户端 编辑:程序博客网 时间:2024/05/04 12:05
1、基类的析构函数声明为virtual的好处?
假设基类CBase,其派生类CChild,有如下代码:
CBase *pBase=new CChild; //new CChild构造对象时,先调用基类CBase的构造函数,然后调用CChild的构造函数,析构时顺序应该恰好相反。
delete pBase;
如果CBase的析构函数定义为virtual,那么pBase指针被撤销时,就会先调用CChild的析构函数,然后调用CBase的析构函数。
而如果CBase的析构函数不是virtual,那么只会调用CBase'的析构函数,从而导致内存泄漏。
2、构造函数为什么不可以声明为virtual型?
虚函数采用虚调用的办法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果创造一个对象,你势必要知道对象的准确类型,因此构造函数不能为virtual型。
3、是否可以把类的每个函数(构造函数除外)声明为virtual型?
不行,因为虚函数是有代价的:由于每个虚函数的对象都必须维护一个v表,因此在使用虚函数的时候会产生一个系统开销。如果仅仅是很小的类,且不想派生其他的类,根本没有必要使用虚函数。
4、虚函数和虚继承
虚函数:类将维护一个虚函数表,来记录对应的函数入口地址
虚继承:派生类将维护一个虚类指针,来指向其父类。
5、虚函数的入口地址和普通函数区别?
每个虚函数在vtable中占了一个表项,该表项保存着虚函数的入口地址。当创建一个包含虚函数的对象时,该对象在头部附加一个指针,指向vtable中相应的位置。调用虚函数的时候,不管你是用什么指针调用的,它先跟据vtable找到入口地址再执行,从而实现了动态联编。而不像普通函数那样简单的跳转到一个固定的地址。
6、基类和派生类地址和布局,下面代码输出
#include "stdafx.h"#include <iostream.h>#include <string.h>class A{int a;};class B{int b;};class C:public A,public B //多重继承{int c;};void main(){C *c=new C;B *b=dynamic_cast<B*>(c);A *a=dynamic_cast<A*>(c);if (c==b) //两端数据类型不同,进行隐式转换,变成 c=(C*)b ; equalcout<<"equal"<<endl; elsecout<<"not equal"<<endl;if (int(c)==int((C*)b)) //比较c和b隐士转换为(C*); equalcout<<"equal"<<endl;elsecout<<"not equal"<<endl;if (int(c)==int(b)) //c和b的值不同,转换为int时也不相同; not equalcout<<"equal"<<endl;elsecout<<"not equal"<<endl;}
- 程序员面试宝典三
- 程序员面试宝典(三)P107
- 程序员面试宝典(三)P107
- 程序员面试宝典
- 程序员面试宝典A
- Java程序员面试宝典
- Java程序员面试宝典
- java程序员面试宝典
- JAVA程序员面试宝典
- Java程序员面试宝典
- 程序员面试宝典
- 《程序员面试宝典》摘记
- 程序员面试宝典
- 程序员面试宝典总结
- 程序员面试宝典笔记
- 程序员面试宝典
- JAVA程序员面试宝典
- 程序员面试宝典一
- android 输入法出现挤压屏幕
- 理解Java Portal规范
- rlwrap
- lucene的分布式搜索-入门篇
- 清扫心灵的扫把
- 程序员面试宝典三
- 九种改变未来世界的革命性技术
- ZOJ 1577 GCD & LCM
- css3选择类别
- PIN码查询网站
- 把excel文档中的内容读取到dataset中
- Spring+JMX(Java Management Extensions)
- 多线程的使用
- 顺时针打印矩阵