C++面试题解答(持续更新中......)
-------------------------------------------------------------------------------------------------------------
1. static成员函数可以访问non-static成员变量吗?为什么?
不能,因为non-static成员变量是依赖于对象而存在的,需要有this指针才能访问。
static成员函数属于类,调用的时候没有this指针。
2. 为什么const成员函数不可修改成员变量?
普通的成员函数在调用时,编译器一般会在形参表中加上一个参数this:
比如类A,它的成员函数是funcA(),编译器会把他变为 A::funcA(A* const p)
调用的时候可以这样理解:
A a;
a.funcA(&a);
如果成员函数用const修饰,它会生成一个指向cosnt对象的const指针: A::funcA(const A* const p)
因此这里不能修改成员变量。
3. 类的static成员变量能用const成员函数修改吗?为什么呢?
可以。因为成员变量不依赖于this指针,跟const成员函数没有关系。
-------------------------------------------------------------------------------------------------------------
1. 为什么浮点型数据不能==或!=比较?
首先,我们要明白,计算机中整型是准确的,浮点型是近似值。
浮点数在计算机中用二进制表示与整型表示不一样,它是采用尾数+指数(M * 2^E)这种科学计数法来表示。
十进制中一个不循环的小数, 可能在二进制中实际是循环小数, 只能用近似值来表示,因此它是有误差的。
比如, 我们在不用计算机时, 把10000个0.1加起来是1000, 而在用浮点数计算时, 0.1是近似的, 加10000次以后误差就会放大, 而不是1000了(VS上调试结果是1000.002869)。
而且,判断两浮点数相等要比较尾数和指数。尾数和指数都相等,两数才算相等。在VC上可以试, float 0.1f 是不等于 double 0.1l的因此应该写为:
const float EPSINON = 0.000001f; if ( fabs(a - b) < EPSINON )
-------------------------------------------------------------------------------------------------------------
1. 什么是多态?多态如何实现?
多态是指同一个操作,表现出多钟实现形式。
多态分静态多态和动态多态,
静态多态是指函数重载,发生在编译期;
动态多态是指函数overwrite,发生在运行时;
(动态)多态主要是通过虚函数表来实现的。有虚函数的基类和派生类各生成一个虚函数表,派生类的虚函数表中同名函数覆盖了基类的同名函数,当基类的指针或引用指向派生类对象的时候,通过这个指针调用虚函数,编译器根据类型信息来判断调用父类还是派生类的虚函数表中的函数,这个过程叫动态绑定。
2.构造函数为什么不能是虚函数?
首先,我们知道虚函数是通过虚函数表vtable来实现的;
其次, 构造函数是在对象初始化时被自动调用的,vtable指针是在对象初始化中分配内存空间的;
在创建对象的时候,这个时候vtable指针还未出现,何来调用虚函数一说,就是本末倒置。
3. sizeof一个空类等于多少?
sizeof一个空类返回1。所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。C++编译器不允许对象为零长度。试想一个长度为0 的对象在内存中怎么存放?怎么获取它的地址?为了避免这种情况,C++强制给这种类插入一个缺省成员,长度为1。
如果有自定义的变量,变量将取代这个缺省成员。
4. 拷贝构造函数与赋值运算符都是将一个对象copy到另一个对象,有什么区别呢?
1). 拷贝构造函数是一种构造函数,它会在产生新的对象时调用;
而赋值运算符是对一个已经存在的对象进行copy操作;
例如:
Class A;
A a;
A b = a; \\调用拷贝构造函数
A c(a); \\调用拷贝构造函数
A d;
d = a; \\调用赋值运算符
2). 函数定义的形式不一样。
ClassA(const ClassA& a);
ClassA& operator= (const ClassA& a);
-------------------------------------------------------------------------------------------------------------
Windows开发
1. 什么是句柄?为什么微软要向我们提供句柄?
在Windows中,句柄是一个32位无符号整数值,和对象一一对应。
windows需要向程序员提供必要地编程接口,在这些接口中,允许程序员访问、创建和销毁对象。但是,出于封装地考虑,
windows并不想向程序员返回指针。指针包含了太多的信息。首先指针给出了对象存储的确切位置;其次,要操作一个指针,
程序员必须知道指针所指对象的内部结构特征,也即,windows必须向程序员暴露相应的数据结构,而这些数据结构也许是
操作系统想向程序员隐藏的。
简单的说,微软为了封装的需要,没有对用户开放窗口指针,因为指针的访问权限太大了,会产生数据安全问题。于是定
义了句柄,即通过句柄你可以访问窗口,但是访问受限。你可以把句柄理解成指针的指针,它指向一个地址,而这个地址又
指向窗口,这样就达到了间接访问的效果。