通过共同讨论解决遇到的知识性问题,及时的把考试与提高班学习无缝连接,把知识与生活相联系,这样既丰富了生活、又培养了乐趣,更有助于理解,提高学习效率。
第一:指针、引用;例如有十个房间,房间的门牌号可以说就是指针,编号在变,指针在变。指针可以为空,指针是个变量,系统为其分配了内存空间,即计算机中指向一块内存,内容为所指的内存的地址(编号)
引用是每个房间的物品,引用不能为空。引用是C++中的概念,我们刚开始学习很容易把引用和指针混淆一起。例题:n是m的一个引用(reference),m是被引用物(referent)。intm;
int&n=m;n相当于m的别名(绰号),对n的任何操作就是对m的操作。例如有人名叫王小毛,他的绰号是“三毛”。说“三毛”怎么怎么的,其实就是对王小毛说三道四。所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。
指针与引用的主要区别:
指针能够毫无约束地操作内存中的任何东西,尽管指针功能强大,但是非常危险。就象一把刀,它可以用来砍树、裁纸、修指甲、理发等等,谁敢这样用?如果的确只需要借用一下某个对象的“别名”,那么就用“引用”,而不要用“指针”,以免发生意外。比如说,某人需要一份证明,本来在文件上盖上公章的印子就行了,如果把取公章的钥匙交给他,那么他就获得了不该有的权利。
第二:继承、多肽、派生
在日常生活当中常见,父亲继承爷爷的相貌、血型等,儿子继承父亲的相貌、血型,这种关系很容易的让我们理解基类(父类),父亲为从爷爷那派生而来即派生类(子类),同样儿子也是父亲的派生类(子类)。
继承:作为儿子的角度来看我们是从父亲那继承的,从长辈角度晚辈是派生的
多继承:可以理解为一个研究员既有研究生的特征,又具有教师的特征,描述事物具有的多种特征。
多肽:就是同一事物在不同条件下的不同表现形式:生活中水在常温下是液体,在100摄氏度以上就是气体,在0摄氏度以下就是固体。
二义性问题:爷爷有连个儿子:父亲和叔叔,爷爷有门电焊技术,传授给了父亲和叔叔,当儿子想学习时,既想从父亲那学习又想从叔叔那学习,这样就可能出现重复,即程序中出现二义性问题,由于多继承中派生出拥有多个基类,如果多个基类中拥有同名的成员,那么,派生类在继承各个基类的成员之后,当调用该派生类成员时,由于该成员标示符不唯一,出现二义性。
第三:类模板:问题域中的事物存在一定的相似性,与之对应,设计的类和类的成员也将表现出相似性,通过抽象将这些相似的类和函数的共性提取出来,用一种统一的方式来描述,形成类模板,
生活中:城市里来来往往的公交车,这个公交车站牌(等车的地方)对于所有可以停车到这的公交车来说这就是公交车的一个类模板,来了公交车就可以停靠的
第四:虚基类:当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类虚基类,在说明其作用前先看一段代码
classA { public: intiValue; }; classB:publicA { public: voidbPrintf(){cout<<"ThisisclassB"<<endl;}; }; classC:publicA { public: voidcPrintf(){cout<<"ThisisclassC"<<endl;}; }; classD:publicB,publicC { public: voiddPrintf(){cout<<"ThisisclassD"<<endl;}; }; voidmain() { Dd; cout<<d.iValue<<endl;//错误,不明确的访问 cout<<d.A::iValue<<endl;//正确 cout<<d.B::iValue<<endl;//正确 cout<<d.C::iValue<<endl;//正确 } |
从代码中可以看出类BC都继承了类A的iValue成员,因此类BC都有一个成员变量iValue,而类D又继承了BC,这样类D就有一个重名的成员iValue(一个是从类B中继承过来的,一个是从类C中继承过来的).在主函数中调用d.iValue因为类D有一个重名的成员iValue编译器不知道调用从谁继承过来的iValue所以就产生的二义性的问题.正确的做法应该是加上作用域限定符d.B::iValue表示调用从B类继承过来的iValue。不过类D的实例中就有多个iValue的实例,就会占用内存空间。所以C++中就引用了虚基类的概念,来解决这个问题。
classA { public: intiValue; }; classB:virtualpublicA { public: voidbPrintf(){cout<<"ThisisclassB"<<endl;}; }; classC:virtualpublicA { public: voidcPrintf(){cout<<"ThisisclassC"<<endl;}; }; classD:publicB,publicC { public: voiddPrintf(){cout<<"ThisisclassD"<<endl;}; }; voidmain() { Dd; cout<<d.iValue<<endl;//正确 } |