虚函数和纯虚函数的区别

来源:互联网 发布:高能金域名都物业 编辑:程序博客网 时间:2024/06/06 12:47

虚函数与纯虚函数的区别:

函数被定义为虚函数,有实现方法;函数被定义为纯虚函数,只有定义,没有实现方法。

虚函数:
class A{public:virtual void foo(){cout << "A:foo()" << endl;}};

纯虚函数:
class C{public:virtual void foo() = 0;  //没有实现方法};


包含虚函数的类可以有自己的对象;包含纯虚函数的类不能有自己的对象。

包含虚函数:
#include<iostream>using namespace std;class A{public:virtual void foo(){cout << "A:foo()" << endl;}};int main(){A *a = new A();a->foo();return 0;}
正确运行,并输出:A:foo()。

包含纯虚函数:
#include<iostream>using namespace std;class C{public:virtual void foo() = 0;};int main(){C *c = new C();return 0;}
报错,该类是抽象的不能实例化。


定义虚函数是为了允许基类的指针可以访问子类的这个函数;定义纯虚函数是为了起到规范作用,使得继承这个基类
的子类必须实现这个函数的方法。

虚函数:
#include<iostream>using namespace std;class A{public:virtual void foo(){cout << "A:foo()" << endl;}};class B : public A{public:void foo(){cout << "B:foo()" << endl;}};int main(){A *a = new B();a->foo();return 0;}
程序正确运行,并输出:B:foo()。

纯虚函数:
#include<iostream>using namespace std;class C{public:virtual void foo() = 0;};class D : public C{public:void foo(){cout << "D:foo()" << endl;}};int main(){D *a = new D();a->foo();return 0;}
程序正确运行,并输出:D:foo()。


纯虚函数:

定义:
纯虚函数是在基类中定义,没有实现方法,继承该类的子类必须定义自己的实现方法。virtual type name() = 0;

意义:
一:为了方便使用多态性,常常在基类中定义纯虚函数。
二:提高了编码效率。
三:很多情况下,基类本身生成对象是不合适的,比如动物基类派生出猫、狗等子类,但是基类本身实例化生成对象
不合适。
为了解决上述问题就引入了纯虚函数,包含纯虚函数的类是抽象类,不能生成对象,只能作为基类派生成其他类
生类必须定义属于自己的纯虚函数实现方法,假如子类只是继承基类的纯虚函数没有是实现方法,那么该子类也是
象类不能实例化。


总结:

1、纯虚函数声明如下:virtual type name()=0;纯虚函数没有实现方法,用来规范派生类的行为,包含纯虚函数
是抽象类,不能实例化,因为实例化这样的抽象数据结构没有意义,但是可以声明指向实现该抽象类的子类的指针或
引用如下:
class C{public:virtual void foo() = 0;};class D : public C{public:void foo(){cout << "D:foo()" << endl;}};C *a = new D();a->foo();
2、纯虚函数,如果子类没有实现方法,那么子类还是抽象类;实现纯虚函数的子类,该纯虚函数在子类中就变成了虚
函数,孙子类可以覆盖该虚函数。由多态方式调用的候动态绑定。

3、对于虚函数,父类和子类都有各自的版本,由多态方式调用的时候动态绑定。
4、虚函数的定义如下:virtual type name() {content};虚函数必须有代码的实现,如果不实现将出现函数未定义的错
误。
5、虚函数是c++实现多态的机制,核心理念是通过基类访问派生类的函数方法。

6、在动态分配堆上内存的时候,析构函数必须是虚函数,但没必要是纯虚函数。
7、友元函数不是成员函数,只有成员函数才可以是虚拟的,因此友元函数不能是虚函数。但可以通过让友元函数调
虚拟成员函数来解决虚拟问题。
8、析构函数应当是虚函数,当delete时将调用相应对象类型的析构函数,如果指针指向的是子类对象,先调用子类的
析构函数,再调用基类的析构函数。

0 0
原创粉丝点击