转自:http://blog.csdn.net/rockics/article/details/7037843
译自Deep C (and C++) by Olve Maudal and Jon Jagger,本身半桶水不到,如果哪位网友发现有错,留言指出吧:)
总结一下第三讲,我们可以知道,相对于第一位候选者,第二位候选者在以下几个方面有更深的认识:
1、 C与C++的联系;
2、 多态方面的技术;
3、 如何正确的初始化一个对象;
4、 Rule of three;
5、 操作符new[]与操作符delete[]方面的知识;
6、 常用的命名约定。
接下来,我们将分享一下几个方面的知识:
1、 对象的生命周期;
2、 Rule of three;
3、 虚函数表。
先来看,恰当地进行对象初始化。赋值与初始化是不一样的。来看这段代码的输出:
- struct A
- {
- A() { puts("A()"); }
- A(int v) { puts("A(int)"); }
- ~A() { puts("~A()"); }
- };
- struct X
- {
- X(int v) { a = v; }
- X(long v):a(v) { }
- A a;
- };
- int main()
- {
- puts("bad style");
- {
- X slow(int(2));
- }
- puts("good style");
- {
- X fast(long(2));
- }
- }
代码输出为:
- bad style
- A()
- A(int)
- ~A()
- ~A()
- good style
- A(int)
- ~A()
再看看对象的生命周期:
C++的一个基本原理是:对象消亡时候需要采取的操作,正好是对象创建时候所采取操作的逆操作。
看下面的代码:
- struct A
- {
- A() { puts("A()"); }
- ~A() { puts("~A()"); }
- };
- struct B
- {
- B() { puts("B()"); }
- ~B() { puts("~B()"); }
- };
- struct C
- {
- A a;
- B b;
- };
- int main()
- {
- C obj;
- }
程序的输出是:
- A()
- B()
- ~B()
- ~A()
再看:
- struct A
- {
- A():id(count++)
- {
- printf("A(%d)\n", id);
- }
- ~A()
- {
- printf("~A(%d)\n", id);
- }
- int id;
- static int count;
- };
- //原文是没有这句的,不过根据C++规范,static数据成员必须在类定义体外定义。
- //谢谢yuxq100指出。
- int A::count = 0;
- int main()
- {
- A array[4];
- }
程序输出:
- A(0)
- A(1)
- A(2)
- A(3)
- ~A(3)
- ~A(2)
- ~A(1)
- ~A(0)
仔细看着张图,也会有所收获:
接下来看看:the rule of three:
If a class defines a copy constructor, acopy assignment operator, or a destructor, then it should define all three.
如果一个类定义了拷贝构造函数、赋值操作符、析构函数中的一个,那么通常需要全部定义这仨函数。
如图示:
接下类看看虚函数表:
看一下这段代码,虚函数表的结构大概如何呢?
- struct base
- {
- virtual void f();
- virtual void g();
- int a,b;
- };
- struct derived:base
- {
- virtual void g();
- virtual void h();
- int c;
- };
- void poly(base* ptr)
- {
- ptr->f();
- ptr->g();
- }
- int main()
- {
- poly(&base());
- poly(&derived());
- }
虚函数表结构如何呢?看图:
简单说明:派生类没有重载f函数,它继承了基类的f函数,因此,派生类的虚函数表的f函数指向基类的f函数。但是,因为派生类重载了g函数,因此,其虚函数表中的g指向自身的g函数。
那么这段代码呢?
- struct base
- {
- void f();
- virtual void g();
- int a,b;
- };
- struct derived:base
- {
- virtual void g();
- virtual void h();
- int c;
- };
- void poly(base* ptr)
- {
- ptr->f();
- ptr->g();
- }
- int main()
- {
- poly(&base());
- poly(&derived());
- }
基类的f函数不是虚函数了,这个时候的虚函数表结构又如何呢?
越多的同事对他们所使用的语言有深入的认识,这对你有什么好处吗?我们不建议(也不实际)要求公司里所有的C/C++程序员都深入理解C/C++。但是你确实需要绝大部分的程序员真的在意他们的专业度,他们需要求知若渴,不断努力,争取不断的加深对语言本身的理解。正所谓:stay hungry,stay foolish:)
现在回过头了看着这两名开发者,也就是我们之前所一直说的候选者。
亲,你觉得这两名开发者之间最大的差别在哪?
关于语言的现有知识吗? 不是!!
是他们对于学习的态度!!
你最后一次上编程方面的课程是什么时候?
第一个候选者这样回答:你什么意思?我在大学里学习编程,现在我通过实践来学习。你想知道什么?
你:那么,你现在在阅读哪些书?
候选者:书?哦,我不需要书。在我需要的时候,我会在网上查询手册。
你:你会跟你的同事谈论编程方面的东西吗?
候选者:我觉得没有必要!!我比他们强多了,从他们身上学不到任何玩意!!
你貌似对C/C++了解的更多,怎么做到的?
第二个候选者:我每天都会学习一些新东西,我真的乐在其中:)
我偶尔也会在stackoverflow.com、comp.lang.c还有comp.lang.c++跟进一些讨论。
我还参加了一个当地的C/C++用户组,我们定期会举行一些讨论会,交流心得。
我看了很多的书,很多很多。你知道吗?James Grenning刚刚写了一本很不错的书:《Test-Driven Development in C》,很值得一看:)
[PS:貌似是:Test-DrivenDevelopment for Embedded C]
我偶尔会被允许拜访WG14W以及G21。
[PS:
ISO WG14:ISO C委员会,具体指JTC1/SC22/WG14 C语言技术工作小组,通常简写为WG14。 ISO WG21:ISO C++委员会,具体指JTC1/SC22/WG21 C++技术工作小组,通常简写成WG21。
此人很牛逼呀:)]
我还是ACCU的会员,这里的人对于编程都有专业精神。我订阅了Overload,CVu及accu的一些综述文章。
[PS:移步看看ACCU的网站,确实应该去看看:
ACCU is an organisation of programmers whocare about professionalism in programming and are dedicated to raising thestandard of programming.
]
候选者接着说:无论何时只要有有机会,我都会参加C/C++课程,倒不是因为跟老师能学到什么东西,而是因为通过和其他同学的讨论,能扩展我的知识面。
但也许最好的知识来源于密切地配合我的同事们工作,与他们交流,分享自己所知的同时,从他们身上学到更多的知识。
(我表示从第二个候选者那学到了很多东西:)
最后,概述:
l 编译器和链接器(连接程序)
l 声明和定义
l 活动帧
l 内存段
l 内存对齐
l 序点
l 求值顺序
l 未定义和未指定
l 优化
l 关于C++的一些玩意
l 对象的恰当初始化
l 对象的生命周期
l 虚函数表
l 以及一些关于专业精神和学习态度的话题
这个时候第一个候选者貌似有所领悟:
第一个候选者:啊?
你:有什么问题吗?
候选者:我真的热爱编程,但是我现在认识到我真的还远远说不上专业。对于如何更好的学习C/C++,您能给我一些建议吗?
你:首先,你必须认识到编程是一件持续学习的的过程。不管你掌握了多少,总有很多知识需要你去学习。其次,你还必须认识到,专业编程最重要的一点是,你必须和你的同事亲密合作。想想体育比赛中,没有人可以做到单凭个人就能赢得比赛。
候选者:好的,我需要好好反省。。。
你:但是话说回来,养成这么个习惯,偶尔去关注一下代码所生成的汇编语句。你会发现很多有意思的东西。使用debugger,一步步的跟踪你的代码,看看内存的使用情况,同时看看处理器到底在执行什么指令。
候选者:有什么关于C/C++的书、网站、课程或是会议值得推荐吗?
你:要学习更多的现代软件的开发方式,我推荐James Grenning写的Test-Driven Development for Embedded C(貌似还没有中文版)。想要更深入的学习C语言,可以参考Peter van/Der Linden的Expert C Programming(C专家编程),这本书虽然成作已经20多年了,但是书上的观点依然管用。对于C++,我推荐你从Scott Meyers的Effective C++(国内侯捷老师翻译了此书)以及Herb Sutter 和Andrei Alexandrescu的C++ coding standards(C++编程规范)。
此外,如果你有机会参加任何于此有关的课程,不要犹豫,参加!只要态度正确,你就可以从老师和其他学生那里学到很多东西。
最后,我建议加入一些C/C++的用户组织,投身于社区当中。具体来说,我非常推荐ACCU,他们很专注于C/C++编程。你知道吗?他们每年的春季都会在牛津大学举行为期一周的与此相关的会议,与会者是来自全世界专业程序员:)或许明年4月份我会在那遇见你?
候选者:谢谢:)
你:祝你好运:)