C++ Virtial
虚函数实际上就是指针 占四个字节
虚函数 优先从子类寻找
虚函数 优先从子类寻找
虚函数声明:virtual 函数类型 函数名(参数列表)=0
1 #include<iostream> 2 using namespace std; 3 class Base{ 4 public: 5 void m() 6 { 7 cout << "it's Base's m() " << endl; 8 } 9 virtual void f() 10 { 11 cout << "it's Base's f()" << endl; 12 } 13 }; 14 class Sub: public Base 15 { 16 void m() 17 { 18 cout << "it's Sub's m()" << endl; 19 } 20 void f() 21 { 22 cout << "it's Sub's f()" << endl; 23 } 24 }; 25 void main() 26 { 27 Base* base = new Sub; 28 base->f(); 29 base->m(); 30 }
上述是以Base为基类,并且Sub派生了Base,同时复写了两个函数f(),m()
当在主函数main里用Base类型的指针指向Sub类型对象,此时利用Base指针调用f()和m(),那么这个时候问题就来了。
在默认情况下Base类的指针会调用当前类型的方法,也就是Base::f(),Base::m(),那么应该输出的都是Base方法中的语句
还有虚函数析构函数,应用在这样一个问题:在基类为抽象类,并且基类指针指向派生类,想要删除这个基类指针指向的内存时
先看第一种情况
1 de<iostream> 2 using namespace std; 3 class Base{ 4 public: 5 Base() 6 { 7 } 8 ~Base() 9 { 10 cout << "Base has deleted" << endl; 11 } 12 }; 13 class Sub: public Base 14 { 15 public: 16 Sub() 17 { 18 } 19 ~Sub() 20 { 21 cout << "Sub has delete" << endl; 22 } 23 }; 24 void main() 25 { 26 Base* base = new Sub; 27 delete base; 28 base = NULL; 29 }
看运行结果
此时是用基类Base指针去操作继承类Sub,在delete Base*指针后,我们可以从结果得到只调用了基类的析构函数,但是派生类的析构函数并没有调用,这相当于内存只是删除了一一半,还有一半内存为删除,导致了内存泄漏,此时则需要用到虚析构函数,来达到调用派生类的析构函数来删除内存空间的目的,也就是下面这种情况:
1 #include<iostream> 2 using namespace std; 3 class Base{ 4 public: 5 Base() 6 { 7 } 8 virtual ~Base() 9 { 10 cout << "Base has deleted" << endl; 11 } 12 }; 13 class Sub: public Base 14 { 15 public: 16 Sub() 17 { 18 } 19 ~Sub() 20 { 21 cout << "Sub has delete" << endl; 22 } 23 }; 24 void main() 25 { 26 Base* base = new Sub; 27 delete base; 28 base = NULL; 29 }
运行结果如下图所示
此时我们可以看到在基类析构函数加了Virtual变成虚函数后,成功地调用了基类和派生类的析构函数,从而实现了基类指针指向内存的完全释放。
虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。
转载:http://www.cnblogs.com/Cc1231/p/4784242.html