这块内容将会增加对运行时多态性、赋值运算符重载、拷贝构造函数、虚函数与纯虚函数、new运算符、指针等的理解。
1、如何体现面向对象的运行时多态性?
(1)通过继承和虚函数机制实现运行时多态;
(2)通过基类对象指针(而非对象)访问虚函数实现动态绑定,如Child d;Parent *b = &d;或者Parent*b =newChild;(在这里栽了跟头,注意后者的用法,在程序运行时才会调用此句代码,可以循环调用,但是会增加内存的消耗,这也是作业中的绘图程序随着图形绘制的越来越多,内存消耗越来越大的原因);
(3)动态绑定相对于静态绑定,虽然稍微降低了程序执行的效率和程序的可理解性,但是增强了程序的可重用性和可扩充性;
(4)动态绑定带来的效率损失并不大,但是也不可滥用动态绑定,应该在明确提高程序可重用性和可扩充性的情况下才运用(比如,作业中的绘图明显可以运用动态绑定);
(5)运行时多态性或者动态绑定是面向对象语言独有的一个特性(区别去面向过程),是C++语言的精髓。
2、虚函数和纯虚函数的理解:
(1)虚函数与纯虚函数在他们的子类中都可以被重写,纯虚函数也属于虚函数;
(2)纯虚函数只有定义,没有实现;而虚函数既有定义,也有实现的代码;
(3)包含纯虚函数的类不能定义其对象,而包含虚函数的类则可以。
(4)引入纯虚函数的目的:一是同虚函数一样,为了实现运行时多态;二是在某些情况下,基类本身实例化对象并不符合常理(比如作业中的绘图,如果实例化一个图形对象显然不合常理),因而声明为纯虚函数,该类就不能实例化对象。
3、拷贝构造函数的理解:
(1)缺省拷贝构造函数使用浅拷贝方式(按位复制),但是当类的成员变量中包含指针时,这种方式会出现指针访问失效的问题,因此,如果希望使用深拷贝方式,就需要自定义拷贝构造函数;
(2)如果自己定义了拷贝构造函数,那么,何时自动调用该拷贝构造函数:a)当声明一个对象时,如果用另一个对象对新对象进行初始化,那么,将自动调用该拷贝构造函数;b)当对象作为参数按值调用传递给一个函数时,编译程序将自动创建该对象的一个副本,并调用拷贝构造函数初始化该对象副本;c)当函数返回一个对象作为返回值时,编译程序将自动创建一个临时对象,临时对象也将调用拷贝构造函数进行初始化。
(3)由(1)和(2)可以知道,如果类中含有带指针的成员变量,并且出现(2)中的情况时,就应该定义自己的拷贝构造函数。
(4)当类的成员变量中包含指针时,必须自定义拷贝构造函数、自定义析构析构函数、重载赋值运算符“=”,这三个措施可以避免使用指针可能带来的问题。其中,前两个措施,正如new和delete一样是对称的,new出现在构造函数中,delete出现在析构函数中。
下面是一些对学习方法的思考。
1、编程,是实现自己想法的一种有效的途径。编程结果的正确性是需要通过对比试验才能进行验证的,一个是编程的结果,一个是自己的想法在理论上的结果或者自己预想的结果,二者对比,方可验证其正确与否。
2、思考,对一个问题的思考,不仅要知其然(解决问题的过程),也要知其所以然(为什么要这样解决),更要知道一个问题的解决方案所蕴含的思想(解决方案的假设或者前提,可行性或者可以说服自己解决方案可行的理由)。
3、思维习惯,一要注重思维的逻辑性、严密性;二要注重思维的发散性(这点可能是自己所欠缺的);三要要养成一种很好的思维习惯。对于第三点,自己最大的缺点是无论在生活中还是学习中,对于困难的问题,总会有一种胆怯的心理,总感觉自己不能做好。要解决这个问题,至少可以从两个方面去考虑:一是按部就班,由易到难,由简单到复杂,一方面解决了简单的问题可以增加自己的信心,另一方面先解决简单的问题,然后慢慢过渡到难的问题,这也是正确解决问题的方法;二是遇到一个难题,只管拼命地去解决,不玩耍不上网,只有解决了才罢休,从而渐渐养成思考的习惯,慢慢形成正确的思维习惯,这样无论遇到多大的难题,也能克服自己的畏难心理,迎难而上。借用一句话:
天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,增益其所不能。
===================================================================================================================================