Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12106
  • 博文数量: 2
  • 博客积分: 190
  • 博客等级: 入伍新兵
  • 技术积分: 40
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-11 15:41
文章分类
文章存档

2011年(2)

我的朋友
最近访客

分类: C/C++

2011-08-31 16:09:57

最初发在QQ空间里,转过来:http://user.qzone.qq.com/31731705/blog/1310540087

上个月面试了一些快要毕业在找工作的学生,有个奇怪的感觉,学校就是学校,搞的东西大多是理论或者算法方面的,听的我是云里雾里,还有就是很NB很酷的那种,动不动就是内核,驱动,有分析Linux内核源码的,有做Windows内核驱动的。还记得当时我问一个学生,为什么你看的是Linux 0.11的代码,不是最新的,学生支支吾吾,说是版本虽然老,但功能齐全,我还是很疑惑,那为什么不是0.08或者是0.3,0.4版本的呢?最终,在我的“追问”下得知了答案,原来有本书就是分析Linux 0.11代码的,他照着这本书看的。

其实对于工程来说,一个重点是动手能力,不管你是研究理论算法,还是写驱动分析内核,都要能够给出解决方案并且付诸实践。很多毕业生,谈起来头头是道,面对一些基本的问题,却是老鼠咬乌龟,束手无策。我有用过一道题,是使用C编写一个模拟实现C++多态应用的一个范例,这题主要考察几点。

  1. C的基本的编程能力,大多数院校中C语言是必修课,即使如此,很多人也写不出基本的程序来。
  2. C++的知识,虽然不直接使用C++编程,但必须理解C++的多态概念,知道多态的应用是怎么一回事,在此基础上,知其然并且知其所以然,要能够理解C++的多态是如何实现的。

意料之中又在意料之外,只有极少数人能够写出象样的答案。意料之中,是因为大多数学生习惯于获取知识,这样就以为我懂了,我会了,而不是去思考背后的一些东西,缺少探索,总结;意料之外,则是学生们没有学习的热情和欲望,上学就是拿学位的,是因为生活压力嘛?这让那些希望工程的渴望上学的孩子们情何以堪。

最后,贴一下这题目的代码,有注释:

  1. // 几个基本的函数,对应抽象类中的虚函数
  2. //
  3. void foo1()
  4. {
  5. printf( "anything foo1 \r\n" );
  6. }

  7. void foo2( int i )
  8. {
  9. }

  10. void foo3( int i, int j )
  11. {
  12. }

  13. // 虚表,包含了虚函数的指针
  14. typedef struct Vtbl
  15. {
  16. void (*pf1)();
  17. void (*pf2)( int );
  18. void (*pf3)( int, int );
  19. }Vtbl;

  20. // 类的虚表
  21. Vtbl g_vtbl = { &foo1, &foo2, &foo3, };

  22. // 基类,开始处是虚表指针,
  23. // 后面是结构成员。
  24. typedef struct Anything
  25. {
  26. //Vtbl *pvtbl;
  27. void *pvtbl;
  28. int field1;
  29. int field2;
  30. }Anything;

  31. // 构造函数
  32. // 也是一个普通的成员函数,需要一个this指针
  33. void InitAnything( Anything *p )
  34. {
  35. p->pvtbl = &g_vtbl;
  36. p->field1 = 0x1234;
  37. p->field2 = 0x5678;
  38. }

  39. // 子类中的虚函数,重载了父类中的同类型函数
  40. void Sfoo1()
  41. {
  42. // 可以考虑调用父类中的函数
  43. // foo1();
  44. printf( "something foo1 \r\n" );
  45. }

  46. void Sfoo4( char *s )
  47. {
  48. printf( "hello %s\r\n", s );
  49. }

  50. // 子类中的虚表,因为内存布局是一样的,
  51. // 直接使用父类的
  52. typedef struct SVtbl
  53. {
  54. Vtbl vtbl;
  55. void (*pf4)( char * );
  56. }SVtbl;

  57. // 子类的虚表
  58. SVtbl g_svtbl = { { &Sfoo1, &foo2, &foo3, }, &Sfoo4, };
  59. // 某个子类,包含父类的内容
  60. // 还有自己的成员
  61. typedef struct Something
  62. {
  63. Anything a;
  64. int field3;
  65. }Something;

  66. // 构造函数
  67. // 也是一个普通的成员函数,需要一个this指针
  68. void InitSomething( Something *p )
  69. {
  70. InitAnything( (Anything*)p );

  71. p->a.pvtbl = &g_svtbl;
  72. p->field3 = 0xabcd;
  73. }

  74. void TestPolymorphism( Anything *p )
  75. {
  76. // 虽然使用的是父类型的指针
  77. // 但虚函数最终会根据对象的真实类型调用。
  78. (*((Vtbl*)p->pvtbl)->pf1)();
  79. }

  80. void TestVtbl()
  81. {
  82. // 子类的一个对象
  83. Something s;
  84. Anything *p = 0;

  85. // 初始化
  86. InitSomething( &s );

  87. p = (Anything*)&s;

  88. // 调用Sfoo4
  89. ((SVtbl*)p->pvtbl)->pf4( "Sfoo4" );

  90. // 测试多态
  91. TestPolymorphism( (Anything*)&s );
  92. }
阅读(1413) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:C S D N,是你过时了吧?

给主人留下些什么吧!~~