这几天一直在读公司的代码,感觉到了虚函数的无比强大与实用,于是好好学习了一下虚函数。由于本人比较菜,所以如果说的不对的话请大家多多指教。
1.相关英文
类:class 基类:base class 子类:sub class 抽象类:abstract class
抽象基类:abstract base class 虚函数:virtual function 纯虚函数:pure virtual function
多态:polymophism 重写:override 重载:overload
2.重写与重载的区别
重写:父类和子类之间的关系,相同的函数名和参数,只是重写了方法,实现不同的功能。
重载:一个类内部的关系,函数名相同,但是参数个数或者参数类型不同,从而实现不同功能。
3.虚函数重写的作用:用于实现多态的机制,精髓就是用基类去访问派生类的函数。参考下面的例子,
你就可以发现虚函数重写与普通重写的区别。
class A //基类
{
public:
A();
void f1(){cout<<This is A1<<endl;} //普通函数
virtual void f2(){cout<<This is A2<<endl;} //虚函数,关键字virtual
~A();
}
class B : public A //派生类
{
public:
B();
void f1(){cout<<This is B1<<endl;}
void f2(){cout<<This is B2<<endl;}
~B();
};
int main(int argc, char* argv[]) //主函数
{
A *marvell=new B(); //精髓,用基类指针指向派生类,不然就没有必要了
marvell->f1(); //调用f1,因为普通函数重写,所以实际调用的是基类的f1()
marvell->f2(); //调用f2,因为虚函数重写,所以实际调用的是派生类的f2().如果派生类中没有实现,则调用基类的f2().
delete marvell;
return 0;
}
结果是This is A1
This is B2
4.虚函数与纯虚函数的区别。
引入原因:纯虚函数与虚函数相同,只是有的时候基类本身生成对象是不合理的。比如动物可以派生出老虎,大象,但是动物本身生成对象是不合理的。很多时候基类是写给别人用的,这个时候就需要用到纯虚函数了。
纯虚函数格式:virtual void f() = 0
区别1:在基类里虚函数是被实现的,哪怕是空实现。在基类里纯虚函数是一定不被实现的,只是一个接口,要留到子类里去实现。
区别2:在派生类里虚函数可以不被实现,但是纯虚函数必须在子类里实现。通常我们把很多函数声明为virtual是一个好习惯,虽然牺牲了一些性能,但是增加了面向对象的多态性,因为很多时候我们不知道基类的函数派生类是否会重写。
区别3:带纯虚函数的类叫做虚基类,也叫做抽象类,这种基类不能直接生成对象,只能被继承并且只能在重写了纯虚函数之后才能使用。
虚函数是为了继承接口和默认行为。
纯虚函数只是继承接口,行为必须重新定义。