§1 从对象谈起
画外音:最近公司又来了一个新人,被分配到我们这个小组。结果一了解,原来她只学过C,没接触过C++,于是,我们的头——Solmyr——就把培训她的任务交给了我。这样,我们这个小组就又多了一个MM,别的小组都快羡慕死了 ^_^ 喔,差点忘了介绍了,新来的叫Young ……
每天的工作还是同往常一样,似乎没什么变化,偶尔看看我那个新徒弟Young,她似乎总是很认真的在看书,似乎还没和大家融合在一起,毕竟,才来了一天啊。
恩,快收工了,我还是按照惯例,打开Outlook,收一下邮件。
突然,MSN 跳出一条信息“Weily,今天收工后有空吗?有空的话就一起吃饭吧,我请 ^_^”。
呵呵,我正愁晚饭呢。于是,我马上回复:“好啊 :)”
……
收工完,就和Young一起去吃饭了。路上,Young就一直在问我学C++学了多久了之类的问题,我也感觉到似乎这顿饭是有目的的……
“师傅啊,你什么时候给我指导一下C++啊?”Young终于说出了请客的目的。
“我?这个 …… 对了,Solmyr叫你去看的《The C++ Programming Language》看了多少了?”我故意扯开话题。
“啊?书我当然在看啊,不过你是Solmyr老大派给我的师傅哦,你可别想推掉培训我的任务哦,否则,这顿饭……”
看不出来,原来她这么精明。还搬出Solmyr的名字来威胁我,这招够狠。
“那么你的想法是?”
“当然是你给我上上课咯”Young使出了她最有魅力的微笑,可我总觉得这个笑容有点邪。
“那还是先回答我刚才问你的问题,那本‘圣经’看的怎么样了?”
“我就是看了那本书,觉得很多东西难以理解,甚至我去找了中文版的,也看不太懂,有好多问题,所以我才要你来给我指导一下啊。而且,我也在网上看过一些评价和讨论,似乎很多人都说这本书不适合入门用……”
“的确,Bjarne自己也说过,这本的确不太适合初学者,不过,如果想要学好C++,那么这本书是必须要看的。那么这样吧,我就把我自己的一些理解和经验逐步地告诉你,这样给你一个对于C++的总体印象,然后,你再去看这本书,就应该有点体会了。”
“好啊,书我一定会看的。那要么我们现在就开始第一节课吧。”Young似乎有一点迫不及待了。
“你应该听说过面向对象吧,也就是Object-Oriented,简称OO。”
“恩,这个我知道。C++就是一种面向对象的高级语言吧。不过我对于OO也就只知道这些了”Young换了一个笑容,似乎很谦逊的样子。
“那么,我们这次就从面向对象开始谈吧。当然,由于时间的关系,我不可能深入的讲解面向对象技术,而且,我也还没达到Solmyr那种境界,所以,我给你讲的这些东西只能算是介绍,也就是入门性质的。”
“好的,具体的我会去看书的,我想书上会有更为详尽的内容的。”
“恩,这个学习态度很好,先表扬一下。喔,在开始之前,我先问你一个问题,你对于‘Object’,也就是‘对象’这个概念有多少了解?”
“对象啊,我觉得就是一样样东西,可以是具体的,也可以是抽象的。”
“大致上可以这么说。其实C++里面的class,也就是类就相当于C中的类型,就像int、char等等,其代表的一种概念(Concept),而对象就是一个个instance(实例)。举个简单的例子,‘书’就是一个class,而一本《The C++ Programming Language》就是书这个class的一个instance。”
“哦,有点懂了。你继续讲吧”
本来想利用她思考的时间吃点菜的,可是我刚用筷子夹起一个菜,还没送到嘴里,她就理解了,可怜我只能将菜放到碗里,等下一个时机。
“C++里有class这个概念的目的,就是为了提供给程序员一种创建他们自己的类型的工具,而且,还要使得这些用户自定义类型和C++的内建类型一样使用方便。所以,一个class,就是一种用户自定义类型。而且,class能够很好的实现数据封装和信息隐藏,使得使用这个class的用户不用去了解这个class的设计细节,只要了解它的公共接口的功能和使用方法就可以了。我记得Solmyr和我说过,你学过C吧,那么应该用过C里面的struct吧?”
“恩,这个用过。在学数据结构的时候还用这个写单链表之类的数据结构呢。”
“C++中的class,从某种意义上说,就是C里面的struct,其区别么,主要就是class中的成员(members)默认为私有的(private),而struct中的members是public的,这是最主要的区别。当然,这个区别可以通过改变访问限制权限来统一的。这些具体的,你都可以从书上看到。下面我们就从例子入手。还记得数据结构中的栈(stack)这个概念吗?”
“记得啊,就是先入后出(FILO)啊。”Young似乎很得意的样子。
“恩。那如果我想建立一个存放整数(int)类型的栈,需要一些什么东西呢?”
“需要一个用于存放变量的数组。”
“数组?如果用数组来建立栈的话,就有一个大小限制。关于这个问题我们先不考虑。那么我再问你,一般对于栈而言,有些什么常用的操作?”
“入栈和出栈,也就是push和pop”Young又一次露出了得意的笑容。
“恩,看来你的数据结构学得还不错嘛……”,我故意拖长最后一个音,似乎带点讽刺,在等她感觉到这点前,我又马上接着问:“这些东西,也就是那个数组和push、pop两个操作是密切相关的吧?”
“应该是的吧。”
“不是应该,是肯定!记住,作为一个程序员要对自己已经明确和掌握的东西有一定的自信!”
“知道了……”
“那么如果在C中,能够很好的体现出这些东西的关系吗?”
“似乎不能。我记得以前写的时候就是写了push和pop两个函数,另外就是建了一个数组,可是看不出直接关系的。”
“对!但如果用C++的class来考虑这个栈,就完全不同了。你所说的那个数组就是这个类的数据成员(data member),而push和pop两个操作就是这个类的两个成员函数(member function),这个类的大致定义就可以像这样……”
我转过身正准备找纸和笔,Young却已经把本子和笔递了过来,看来她的确早有预谋啊。我接过本子和笔,写下了:
class IntStack
{
public:
……
bool push(int data);
int pop();
……
private:
……
int _stack[MAX];
};
“这就是我刚才所说的那个整数堆栈类的大致结构了。当然,我们这里忽略了很多细节,就好比构造函数、析构函数、拷贝构造函数等等,而且一个堆栈用一个数组来实现也不好,这些细节以后我们会一个个来关注的。C++里其实还有很多特性,等讲到泛型和模板(Template)的时候,我们就可以将这个堆栈作成一个模板类。呵呵,你要学的东西还有好多,一点点来啦。”
“喔,知道了,你还要说的就是‘后面的路还很长是吧’?”Young眨着眼睛,微笑着。
“你怎么知道我要这么说啊?”
“这个啊?地球人都知道啊!呵呵……”
昏倒。的确,这句话我常说,熟悉我的人都知道,可是Young才来了一天啊,在吃这顿饭之前,和我说过的话大概不超过五句吧,她怎么会知道?
哎呀,不好,饭还没吃啊。当我想到这点的时候,发现已经完了,桌上的几个菜基本上都已经被“消灭”了。看来,我的晚饭问题还是没解决。而她,似乎很有收获的样子。我终于理解了当年Solmyr带Pisces的时候的痛苦了。
注:
1. 参考了Bjarne Stroustrup的《The C++ Programming Language》
2. 我的C++水平么也不高,写这份小品文式的教程的目的是为了帮助那些还没有入门的初学者,也帮我自己系统地重新学习一下C++ ^_^