两个半月没更博客,人变得更菜了,开始挖个复习大坑。
1.C++的三大特性:封装、继承、多态。
2.多态:用一句话来概括,多态就是同一函数(方法)作用于不同的对象时,可以有不同的解释,产生不同的执行结果。在面向编程中使用多态,能大大提高程序的可扩充性
- 多态主要是为了解决很多派生类都和基类有同一个同名函数的问题,有了多态之后,编译器就可以通过判断指针指向的地址来判断运行哪一个类中的函数。
- 动态多态会伴随着虚函数,虚函数是在基类中使用关键字virtual声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
- 多态例子:
#include <iostream>
using namespace std;
class A {
private:
int nVal;
public:
void Fun()
{ cout << "A::Fun" << endl; };
void Do()
{ cout << "A::Do" << endl; }
};
class B:public A {
public:
virtual void Do()
{ cout << "B::Do" << endl;}
};
class C:public B {
public:
void Do( )
{ cout <<"C::Do"<<endl; }
void Fun()
{ cout << "C::Fun" << endl; }
};
void Call(B & p) {
p.Fun(); p.Do();
}
int main() {
C c;
Call( c);//Do函数会因为多态而调用C的,Fun函数因为B没有只能调用B的基类A的
return 0;
}
这个例子中,函数接受的参数是B类的引用,但是主函数里提供的参数是一个C类,此时Do函数因为在B类中声明了虚函数,通过多态会运行C中的同名函数。
3.虚函数:虚函数其实就是函数前面声明了virtual关键字的函数,但是他有很多需要注意的特性:
- 在构造函数或析构函数中调用虚函数,不是多态。编译时即可确定,调用的函数是自己的类中或基类中的函数。
- 在非构造函数、非析构函数的函数中调用虚函数,是多态。
- 派生类中与基类虚函数同名同参数表的函数,不加virtual也自动成为虚函数(上面的代码例子就没有加)
- 不可以以虚函数为构造函数
- 通过基类的指针删除派生类时,通常只调用基类的析构函数,派生类析构函数不能得到执行,此时需要把基类的析构函数声明为虚函数。为了避免此类问题,一般只要一个基类只要有虚函数,就要把他的析构函数声明为虚函数
- 编译不考虑实际执行情况,因此调用时类的指针指向的不能是其他类的私有函数,即使实际运行的是一个公有函数。
4.纯虚函数和抽象类
纯虚函数没有函数体,在类中声明
class A{
public:
virtual void func()=0;
}
包含纯虚函数的类叫抽象类,抽象类只能作为基类派生其他类,不能声明对象。
5.多态的实现原理:动态联编
每一个有虚函数类的派生类都会有一个虚函数表,这个类的每一个对象都会存放一个指向虚函数表的指针,虚函数用来存放虚函数的地址,占四个字节。
参考博文:C++多态