1.虚函数ios
虚函数主要利用在多态的实现上,当基类的成员函数为虚函数时,它的子类函数若是也实现了这个虚函数,那么就能够实现多态的功能。app
// Test1.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "iostream" using namespace std; class A { private: int valueA; public: A(); A(int value); ~A(); virtual void print(); }; //The class A realize. A::A() { valueA = 0; } A::A(int value) { valueA = value; } A::~A(){} void A::print() { cout << "This is A print and Value is :" << valueA <<endl; } class B:public A { private: int valueB; public: B(); B(int value); ~B(); void print(); void draw(); }; //The class B realize. B::B() { valueB = 0; } B::B(int value):A(value) { valueB = value; } B::~B(){} void B::print() { cout << "This is B print and Value is :" << valueB << endl; } void B::draw() { cout << "This is B draw and Value is :" << valueB << endl; } int main(void) { A *objectA = new A(10); B *objectB = new B(20); A *objectC = objectB; objectA->print(); objectB->print(); objectC->print(); return 0; }
上述代码输出为:函数
从而咱们能够清楚的看出objectC虽然属于A类的,可是因为多态的原理,A类中的print函数被B类给重载了,从而objectC输出的便是B类的print;还有一点值得注意要的是虚函数能够传参,但最好不要带有默认参数,不然会形成误解,假若咱们将print函数传入默认参数,main函数不变的话,代码以下(这里只写了A,B也应同理的改写print函数并将默认参数设为3):spa
class A { private: int valueA; public: A(); A(int value); ~A(); virtual void print(int value = 1); }; //The class A realize. A::A() { valueA = 0; } A::A(int value) { valueA = value; } A::~A(){} void A::print(int value) { cout << "This is A print and Value is :" << value <<endl; }
那么输出的结果为:指针
会惊讶的发现不是说好的:objectC输出的是B类的print的么?从而objectC不是应该输出为3么?为何会这样呢?答案是函数依然调用的是B的print然而传参是A的print函数的参数;这就是为何不建议为虚函数设置默认参数的缘由所在。code
2.析构与虚析构函数对象
普通的析构函数如上例:~A(); 而后在实现它的地方执行内存释放等操做。而虚析构函数为:virtual ~A(); 即在析构函数前加入关键字virtual便可。一般在编写程序的过程当中要求基类的析构函数必须为虚析构函数(抱歉上述代码本人没有按要求使用用虚析构函数,正常必须使用虚析构)。缘由其实从上面的小节中就可知道,当实现多态时,即利用相似指针 objectC这种方式的时候,当objectC对象处理完了,须要调用析构的时候,这时候实际上在调用A的析构函数时,咱们一样也要调用B的析构函数,普通的析构函数无法实现,而虚析构函数却能够顺利的实现,具体原理若是你完全明白第一节的内容就会明白虚析构函数的缘由,所以切记在编写程序的时候基类的析构函数必须为虚析构函数!!内存
<未完待续>io