C++ 程序设计 读后感

来源:互联网 发布:vip后缀域名备案问题 编辑:程序博客网 时间:2024/05/22 11:54

这本书应该算这边,已经是读的第三遍了,一直用本子做笔记,突然举得我应该把笔记心的写在博客上,便于自己的翻阅和记忆;真的是每一遍都有不同的收获,前两遍在阅读的时候,我真的还不太懂什么是C++,什么是继承、组合、virtual函数、类,但我读这边时,也就是这几天,突然举得自己有很大的提高,希望这是我开发生涯的一个好的开始,自己一定要再接再厉,不断地修炼自己;

第12章  多态和虚函数

在同一个类中是不能定义两个名字相同、参数个数和类型都相同的函数,否则就是“重复定义”。但是在类的继承层次结构中,在不同的层次中可以出现名字相同、参数个数和类型相同而功能不同的函数。这是合法的,因为不在同一个类中。编译系统按照同名覆盖的原则决定调用的对象。

虚函数的作用,是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。

virtual viod display();

当把基类的某个成员函数声明为虚函数后,允许在其派生类中对该函数重新定义,赋予它新的功能,并且可以通过指向基类的指针指向同一类族中的不同类的对象,从而调用其中的同名函数。由虚函数实现动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的相应。

虚函数的使用方法是:

(1)在基类用virtual声明成员函数为虚函数。这样可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地调用。

在类外定义虚函数时,不必再加virtual.

(2)在派生类中重新第一次函数,要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同,并根据派生类的需要重新定义函数体。

C++规定,当一个成员函数被声明为虚函数后,其派生类中同名函数都自动成为虚函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在每一层声明该函数时都加vitrual,是程序更加清晰。

如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。

(3)定义一个指向基类对象的指针变量,并使他指向同一类族中的莫以对象。

(4)通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。

函数重载处理的是同一个层次上的同名函数问题,而虚函数处理的是不同派生层次上的同名函数问题,前者是横向重载,后者可以理解为纵向重载。但与重载不同的是:同一类组的虚函数的首部是相同的,而函数重载时函数的首部是不同的(参数个数和类型不同)。

静态关联与动态关联

    确定调用具体对象的过程成为关联。

函数重载和通过对象名调用的虚函数,在编译实际可确定其调用的虚函数属于那一个类,其过程称为静态关联,由于是在运行前进行关联的,故称为早期关联。函数重载属静态关联。

在运行阶段把虚函数和类对象“绑定”在一起,一次,此过程称为动态关联。这种多态性是动态多态性,既运行阶段的多态性。(也称为滞后关联);

在什么情况下应当声明虚函数:

(1)类的继承层次结构中,对基类的虚函数重新定义;

(2)一个成员函数被声明为虚函数后,在同一个类族中的类就不能在定义一个非virtual 的当该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数。

当带有虚函数时,编译系统会为该类构造一个虚函数表(vtable),它是一个指针数组,存放每个虚函数的入口地址。

虚析构函数:

将基类的析构函数声明为虚函数,这将是所有的派生类的析构函数自动成为虚函数。这样,如果程序中用delete运算符准备删除一个对象,而delete运算符的操作对象是指向派生类对象的基类指针,则系统会调用相应类的析构函数。

构造函数不能声明为虚函数。这是因为在执行构造函数时类对象还未完成建立过程,当然谈不上函数和类对象的关联。

纯虚函数与抽象类

一、纯虚函数:

vittual flot area() const =0;   //存续函数

这就将area声明为一个纯虚函数。纯虚函数是在声明虚函数是被“初始化”为0的函数。声明纯虚函数的一般形式是

virtual 函数类型  函数名 (参数表类)=0;

注意

1 纯虚函数没有函数体;

2 最后面的“=0”并不表示函数返回值为0 ,它只起形式上的作用,告诉编译系统“这是存续函数”;

3 这是一个声明语句,最后应该有分号;

纯虚函数只是函数 的名字而不具备函数的功能,不能被调用;可以说他是“徒有其名,而无其实”。他只是通知编译系统“在这里声明一个虚函数,留待派生类中定义”。

在派生类中对此函数提供定义后,它才能具备函数的功能,可以被调用;

纯虚函数的作用是在基类中为其派生类保留一个函数名字,以便派生类根据需要对他进行定义。如果基类中没有保留函数名字,则无法实现多态性。

二  抽象类

定义这些类的唯一目的使用它作为基类去建立派生类;

不用来定义对象而只作为一种基本类型用作继承的类,称为抽象类,由于它常用作基类,通常称为抽象基类。

凡是含有纯虚函数的类都是抽象类。因为纯虚函数是不能被调用的,包含纯虚函数的类是无法建立对象的。抽象类的作用是作为一个类族的共同基类,或者为一个类族提供一个公共接口。

在抽象类里定义的虚函数后纯虚函数,在派生类中,如果用到,就重新定义;

(1)静态关联 :

先定义类对象,然后通过类对象调用类里的函数,这属于静态关联,在编译阶段就能确定调用哪个类的函数。同时用重载运算符“<<”来输出个对象的信息,可以验证对象初始化是否正确;

(2)动态关联:

定义一个指向基类shape对象的指针变量pt ,使它先后指向3个派生类对象point,circle和cylinder,然后通过指针调用个函数,如pt->shapeName(),pt->area(),pt->volume().这时是通过动态关联分别确定应该调用那个函数。分别输出不同类对象的信息。

抽象基类结论:

(1)一个基类如果包含一个或一个以上纯虚函数,就是抽象基类。抽象基类不能也不必要定义对象;

(2)一般并不是现实存在的对象的抽象;

(3)在类的层次结构中,顶层或最上面的几层可以是抽象基类;

(4)抽象基类是本类族的公共接口;

(5)区别静态关联和动态关联;

(6)如果在基类声明了虚函数,则在派生类中凡是在该函数中相同的函数名、函数类型、参数个数和参数类型函数,均为虚函数(无论在派生类中是否用virtual声明)。

(7)使用虚函数提高了程序的可扩展性。

 

 

输入流输出流

C++的输入输出