C++题目汇总
说明一下++p 与 p++ 的区别。
正确答案: B 你的答案: B (正确)
没有区别
++p更好一些
p++更好一些
和编译器有关
假设这样的一个例子:
1
2
3
|
int p = - 1 ; int y = 0 ; y = p++ + ++P; |
先分析一下它的汇编代码(没有优化):
1
2
3
4
5
6
7
8
9
10
|
subl $ 40 , %esp ; 分配 40 字节 movl $ 1 , - 16 (%ebp) ; 存储 p movl $ 0 , - 12 (%ebp) ; 存储 y movl - 16 (%ebp), %eax ; 这 3 步执行 p++ leal 1 (%eax), %edx movl %edx, - 16 (%ebp) addl $ 1 , - 16 (%ebp) ; 这 2 步执行 ++p movl - 16 (%ebp), %edx addl %eax, %edx ; 相加操作 movl %edx, - 12 (%ebp) ; 结果写回 y |
可以看出p++需要3步,++p需要2步,而且修改p的值是不一样的,看出++p的效率比p++的高。
指针++和i++是类似的。
因为i++在计算时,会用到中间变量存储,会占用更多的内存和时间。所以++i更好。
如下程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#include "stdio.h" class Base { public : Base() { Init(); } virtual void Init() { printf ( "Base Init\n" ); } void func() { printf ( "Base func\n" ); } }; class Derived: public Base { public : virtual void Init() { printf ( "Derived Init\n" ); } void func() { printf ( "Derived func\n" ); } }; int main() { Derived d; ((Base *)&d)->func(); return 0; } |
该程序的执行结果
正确答案: B 你的答案: C (错误)
Base Init Derived func
Base Init Base func
Derived Init Base func
Derived Init Derived func
在构造函数不要调用虚函数。在基类构造的时候,虚函数是非虚,不会走到派生类中,既是采用的静态绑定。显然的是:当我们构造一个子类的对象时,先调用基类的构造函数,构造子类中基类部分,子类还没有构造,还没有初始化,如果在基类的构造中调用虚函数,如果可以的话就是调用一个还没有被初始化的对象,那是很危险的,所以C++中是不可以在构造父类对象部分的时候调用子类的虚函数实现。但是不是说你不可以那么写程序,你这么写,编译器也不会报错。只是你如果这么写的话编译器不会给你调用子类的实现,而是还是调用基类的实现。
在析构函数中也不要调用虚函数。在析构的时候会首先调用子类的析构函数,析构掉对象中的子类部分,然后在调用基类的析构函数析构基类部分,如果在基类的析构函数里面调用虚函数,会导致其调用已经析构了的子类对象里面的函数,这是非常危险的。