|
|
2009爱立信面试题' G! l& |; s1 `' w1 S
, N. j2 j$ t$ g6 A
Zz+ l# k E9 U1 z7 f( d
4 `! r. z* A1 t! z( J6 ](1)下面程序运行结果是什么:9 ~ r8 A* K) O# U: v" c
#include "stdio.h"! @6 m4 l F, k9 [( A' Z1 O: z
class test( N* M U& ^8 o" A8 \1 B
{: e3 E0 G. j/ C# J
public:
0 g* k' v& V+ B- Y/ R4 H3 c3 vtest(){}3 K7 b7 e3 n- O' H, ]- V
void hello(){ printf("hello\n");}( n( i! m7 l" y( } f9 H+ r. e" L
};
% G7 g0 u( Y# [/ vvoid main()3 H E, M0 ~) C5 D0 `& R! k
{
/ v5 p; n' G+ ?4 b5 e- {7 } test* p=new test();8 A$ \' L& T6 n2 l# |# b: ^
p=NULL;
; F0 H: K2 D1 ` p->hello();( O# Q& o* N; J
}
2 V4 T! S2 N$ I; U. `$ l# a事实是输出了hello,虽然在调用p->hello();之前已经给p赋值为NULL了(即0值),但是p依然可以调用test类的函数。我对此的解释是只要是test类的成员函数和成员变量放在不同的存储区(事实上也是如此),只要是test类型的指针就能调用test的成员函数,前提是函数里没有涉及到成员变量。比如下面的代码编译无误但运行会报错:
' C" l" U) r5 F) P' f#include "stdio.h", ^" Y. O+ m+ x7 ~6 Q. W
class test
7 t0 W/ H* F# E+ k2 X& i! t{
/ r; G# p7 W' v, N0 w. _private: G+ k$ ~/ h8 d2 g5 Q }! x4 ^4 u
int i;- u0 w- T3 y7 |$ ^5 F1 ?
public:3 _# n0 J8 L/ n! G' w) V' g
test(){i=1;}4 D" E2 o2 J2 O- F% r" c2 X
void hello(){printf("%d\n",i);}
: H) [! A6 D c# V ~3 T# i8 \! ?};
& @( c- P5 h' h6 s( L. B0 Ovoid main()) s$ J0 t" h, b1 F" L9 Y f
{, }4 u2 t. \: ~
test* p=new test();
# O" Q; Q8 c, {p=NULL;; N* I% d+ V+ j. j2 ~$ N# d, K
p->hello();
/ Z$ d5 {% A7 a* n0 q}, l2 s, i% d; O' i8 z: A. I
如果将p=NULL注释掉就无误,就会输出1.- f \" ~! _3 H( I H! l' f" H
注意:另外上面两个例子中如果把p=NULL换成delete p;也会有相似地效果,第一个依然输出hello,第二个输出个随机值(不报错)。大家不妨调试看看。 N* w: M) q5 P% W
(1)C++的构造以及析构顺序
+ N; Q4 B6 f1 a' T#include <iostream>9 s& @1 {8 K3 S" `5 }' K5 x. x- s
using namespace std;2 i, a7 b9 D) J
class A
# T( a1 i ]5 r+ L8 x8 B8 P{
! N3 f' l9 S4 u3 b Epublic:0 Y8 M1 ~3 `. G4 U4 A6 ?
A(){cout<<"A"<<endl;}$ k1 L* C0 v6 _$ h/ f( A
~A(){cout<<"~A"<<endl;}
4 q0 w2 p, A1 {# [( \};5 u K I4 }9 V( h2 I
class B : public A
1 R; T' \, j4 t) B8 M2 C{! t6 R7 N' f, A, i: o3 D
public:
. }/ X# e* Q/ a$ V3 CB(){cout<<"B"<<endl;}
b8 g; X( b" b2 h, X" h: Nvirtual ~B(){cout<<"~B"<<endl;}
- H) X* K5 [& N3 u1 y0 c};
0 ?% ~5 d+ s/ d Bclass C : public B
, K( z, X$ I( E- g9 |2 C' k{
. f3 ^: B; t, T6 p2 W! x( v# R( Zpublic:
n& a3 [! N( }; V) z# hC(){cout<<"C"<<endl;}6 A9 A$ z' \; g/ {+ J1 E0 T3 h
~C(){cout<<"~C"<<endl;}& m9 H2 R8 H: l$ F! H
};
* @1 X! p( M1 ~6 [; O$ s+ U7 E
. p& _( Y9 r! D: Tvoid main()
# v+ ]: R* A& G' x( l0 n B) _{1 i! c/ ~- s. B
/ R9 f. Y4 F# T% t8 Q: P
A *a=new A();' Q# ^# C. P1 C5 _# G6 B2 [3 c
B *b=new B();
! H4 [0 J, n8 s! T" m C *c=new C();( V s5 Q) [2 Y7 z( w. C6 t
A *d=new B();$ H6 |$ _. y) l; F
A *e=new C();: o4 M3 m r( ]2 u# [
B *f=new C();
* P: d0 Q0 J5 ?
. ?5 J* a& Y/ W* ` w- y+ }delete a; cout<<"---------------\n";
& S3 }& a i3 z( t: ^delete b; cout<<"---------------\n";) z3 k# H0 g' p! s" f9 |1 s l, m
delete c; cout<<"---------------\n";5 g' u* E9 z% S! M. U$ |% i% n
delete d; cout<<"---------------\n";) p% e8 [$ V% _( F1 v! _1 |
delete e; cout<<"---------------\n";9 |& _, J' M4 }3 v n, y
delete f; cout<<"---------------\n";
3 {! `. @( V6 ~1 M. B+ c- b}/ l% [6 Z* o) ^0 e
这个代码在Dev C++下顺利通过,在VC6下有点问题,大家自己看结果。
: y: |% l. _- ?6 }$ }这里要注意几点的是:首先,A*类型的指针不能赋给B*类型指针(强制转换也不行),不过有两个例外,一个是void*指针,另一个是当A和B有继承关系时。
6 m5 }; _5 o7 x( u) `- W7 F其次只能将子类类型指针赋值给父类(上转型),而不能将父类对象地址赋给子类指针,因为子类默认包含了父类的所有成员(当然有些被隐藏,呵呵)& K$ o2 | f4 t, Z# T% N
(2)面试的诡异题目
/ d/ F& {: P( D0 ^; }* t大意就是如果你 test *p=new test[20];. p0 v6 q! ]) d5 ~: A+ {: a
然后释放的时候用delete p;会怎样?(明显这样做是不对滴……)# X1 D7 U+ g4 [$ N9 f& \9 W
答复是会调用p[0]的析构函数,然后p[1]到p[19]没人管。另外还问是否造成内存泄露……/ ?) |, j& t) \" m
4 h- z; W7 l+ g& h8 a+ a0 O
Zz5 P: _( u- x( ^6 h: ?
爱立信(Ericsson)求职俱乐部:http://bbs.aftjob.com/group-298-1.html
0 f' j5 l/ u I爱立信(Ericsson)笔经面经汇总:http://bbs.aftjob.com/thread-416668-1-1.html8 {" Z+ {) ^8 N1 g
——# f. c& L3 Q' N" a* k; D
查看名企2012校园招聘最新进度,请关注阿凡提求职公共日历:http://www.aftjob.com/home.php?mod=space&do=calendar |
|