|
|
2009爱立信面试题
2 G- k/ L" b0 M1 V" q( ?
; i1 t0 y7 n- Z$ t: XZz
4 E+ J- K5 L6 G5 N' ?5 S2 ^5 R$ L) \: M* j, P' l
(1)下面程序运行结果是什么:( e: y6 y, P$ N) H$ g
#include "stdio.h"+ \: c1 m6 a6 J7 |! N
class test
; l- }) \$ E. N+ b( w' F) b' b- O( r# p- v{, w) y1 e9 Z, U5 x( b4 J% D
public:6 c( z" I. X& {; l
test(){}
; p8 {: F( {- Lvoid hello(){ printf("hello\n");}6 ^8 ?3 m6 h' v3 g: J9 B, m8 m
};
9 w1 f" U" r8 F# x- X! Y {7 [. Hvoid main()
# F2 ]% Z5 ^+ w+ J' {{
, e3 A( A! _. q; p3 H' b P9 @/ I test* p=new test();
) N+ v- h$ |; i" o* R2 I p=NULL;
3 J& C6 v4 F2 q9 m5 d$ T p->hello();; J) R# V8 Z+ u; J1 O
}
" e1 [; v( y3 h$ T! Q3 ?; Y2 Z事实是输出了hello,虽然在调用p->hello();之前已经给p赋值为NULL了(即0值),但是p依然可以调用test类的函数。我对此的解释是只要是test类的成员函数和成员变量放在不同的存储区(事实上也是如此),只要是test类型的指针就能调用test的成员函数,前提是函数里没有涉及到成员变量。比如下面的代码编译无误但运行会报错:
! ^9 `) t/ |6 Z% c& X#include "stdio.h"+ ?) S, d0 r; y2 d! I" }
class test
. S- s$ q+ V! k# R{
5 Z& N1 @7 r3 |0 S* x9 Q$ gprivate:' g9 I' d! X* ^6 J# Z$ h
int i;
$ r1 G6 A, G7 _2 `; c0 d1 tpublic:% r6 h6 \/ M% O% ^9 g
test(){i=1;}
' o* i9 `( y' Nvoid hello(){printf("%d\n",i);}1 i9 x% a9 Z# @4 o' G0 k
};
; e/ t! y9 y6 Nvoid main()( D+ i+ E! S1 C1 M
{
7 i6 Q/ A* ^; ` test* p=new test();* [ q8 N# P* j S/ w
p=NULL;
: v5 l j2 s7 [; F3 R7 s) @' ^- Pp->hello();
- d# Q( b- ^9 f- x6 B' ?}
( I7 N$ K7 [; u9 o( t: W如果将p=NULL注释掉就无误,就会输出1.7 V4 ]7 A2 E8 s* G5 R6 h* \
注意:另外上面两个例子中如果把p=NULL换成delete p;也会有相似地效果,第一个依然输出hello,第二个输出个随机值(不报错)。大家不妨调试看看。
: p+ O F A3 ]$ c* }0 L3 s(1)C++的构造以及析构顺序
! R6 E6 `# [. c* g7 f% m#include <iostream>) [; p$ l; j. a9 }
using namespace std;
4 y& f- Y) W3 b# D, h0 Iclass A
" b" Y8 z) Q8 Y8 T& T{1 ^$ T1 r) x K- b' g
public:
% k0 u* w& J7 J& D& |A(){cout<<"A"<<endl;}8 ]1 D, `7 G% _% q! F( q
~A(){cout<<"~A"<<endl;}& f" q: p9 x) d+ S* T9 R
};
4 E/ ^( ~# h0 U) c: Z# Wclass B : public A m) Q! U2 P/ s. y0 `) N* R
{
) T& d& U) U Z, G- opublic:
1 r" _( h0 {& v6 i" @, e" Q0 FB(){cout<<"B"<<endl;}- Z) ]% R# L& {/ X5 B* V! m" e0 P
virtual ~B(){cout<<"~B"<<endl;}
5 E7 r5 g6 Q( R* e};; d1 ^3 v- {' | V( V
class C : public B8 j* H8 A% Z" Y+ F
{, ]" h" ^1 E/ \; i/ O
public:9 P& J1 U$ i' `4 f* a! v/ `2 j; W
C(){cout<<"C"<<endl;} q5 e8 v( N7 `3 B& ]! G( e! x5 D, ~4 N, L
~C(){cout<<"~C"<<endl;}% m' M: z1 y# ?/ t3 [4 R
};
4 J; p4 M+ M9 Y y5 q: D* C" s& U- [: V6 f/ k
void main()/ Y1 I$ o0 P- M. {0 O; t+ ^
{3 f; I7 t X+ o% X, J$ t
2 `6 d; j0 H& a5 f, Y* iA *a=new A();3 S) T9 W9 H% s/ \4 a
B *b=new B();1 b; z' e+ S0 [4 B6 D
C *c=new C();9 x, z, |' S+ q' W
A *d=new B();
- L' G/ j5 T( j! C* M* iA *e=new C();
i. p$ r& F5 l B- AB *f=new C();6 s6 @! ?! c9 E
. V' D# Q |: x; x
delete a; cout<<"---------------\n";' m9 @5 K* q: D P8 k% Z* Y/ c
delete b; cout<<"---------------\n";; |2 f4 ]( `( O
delete c; cout<<"---------------\n";
) g8 E* d9 f9 P+ P) c% x9 qdelete d; cout<<"---------------\n";. b0 O! M( ]6 S& b
delete e; cout<<"---------------\n";
1 E" ~) @$ ?0 Idelete f; cout<<"---------------\n";3 ?+ G" p* J6 L% w
}1 U- Z% x% {; R& h/ A2 v6 i
这个代码在Dev C++下顺利通过,在VC6下有点问题,大家自己看结果。& x! c2 g5 f" _% t4 k
这里要注意几点的是:首先,A*类型的指针不能赋给B*类型指针(强制转换也不行),不过有两个例外,一个是void*指针,另一个是当A和B有继承关系时。2 R' q s6 S4 N
其次只能将子类类型指针赋值给父类(上转型),而不能将父类对象地址赋给子类指针,因为子类默认包含了父类的所有成员(当然有些被隐藏,呵呵)& k3 D% ^* ]: x
(2)面试的诡异题目
6 s$ q9 f. _& Q/ J7 y! @- [! N大意就是如果你 test *p=new test[20];
) j1 I" K% U5 D. ~0 O3 e然后释放的时候用delete p;会怎样?(明显这样做是不对滴……)8 E4 v3 o' {' x M* y; m
答复是会调用p[0]的析构函数,然后p[1]到p[19]没人管。另外还问是否造成内存泄露……
4 Y8 D7 J" }; @* L$ B6 b5 z
. s+ D4 _# Y4 w* r1 [3 SZz
0 G' X. Z. Y5 `$ L/ m爱立信(Ericsson)求职俱乐部:http://bbs.aftjob.com/group-298-1.html
7 {# F! x6 H8 t' W4 {- [爱立信(Ericsson)笔经面经汇总:http://bbs.aftjob.com/thread-416668-1-1.html
) @( r+ @2 F$ ~. f+ ?——
2 Y; |7 ?+ S" Z查看名企2012校园招聘最新进度,请关注阿凡提求职公共日历:http://www.aftjob.com/home.php?mod=space&do=calendar |
|