标签:
1.什么是虚函数?
答:在C++的类中,使用virtual修饰的函数。
例如: virtual void speak() const { std::cout << "Mammal speak!\n"; }
2.虚函数有什么作用?
答:虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
例如:定义一个父类Mammal类
1: class Mammal
2: {3: public:
4: Mammal():age(1) { std::cout << "Mammal constructor ...\n"; }
5: ~Mammal() { std::cout << "Mammal destructor ...\n"; }
6: void move() const { std::cout << "Mammal, move one step\n"; }7: virtual void speak() const { std::cout << "Mammal speak!\n"; }8:9: protected:
10: int age;
11: };
再定义一个子类Dog类,继承Mammal类,子类Dog类中重新定义了speak()函数
1: class Dog : public Mammal2: {3: public:
4: Dog() { std::cout << "Dog constructor ...\n"; }
5: ~Dog() { std::cout << "Dog destructor ..\n"; }
6: void wagTail() { std::cout << "Wagging tail ...\n"; }7: virtual void speak() const { std::cout << "Woof!\n"; }8: void move() const { std::cout << "Dog moves 5 steps ...\n"; }9: };
现在通过指针来访问基类和子类中的同名函数
1: int main()
2: {3: Mammal *pMam = new Mammal;
4: Mammal *pDog = new Dog;
5: pMam->speak();6: pDog->move();7: pDog->speak();8: return 0;
9: }
运行结果:
3.虚函数的使用?
首先,明确一点,虚函数是用来实现多态的,如果类继承中无需实现多态,请不要使用虚函数,后面会讲到,使用虚函数实际上会增加开销。
3.1单继承的形式
由Mammal派生出多个子类,每个子类唯一的继承Mammal父类,可以看到,每个子类都有一个虚函数 void speak()重写了父类中的虚函数,这是因为就这种动物类而言,每一种子类的发声都不同,需要重新定义。
1: #include <iostream>2:3: class Mammal
4: {5: public:
6: Mammal():age(1) { }7: ~Mammal() { }8: virtual void speak() const { std::cout << "Mammal speak!\n"; }9: protected:
10: int age;
11: };12:13: class Dog : public Mammal14: {15: public:
16: void speak() const { std::cout << "Woof!\n"; }17: };18:19: class Cat : public Mammal20: {21: public:
22: void speak() const { std::cout << "Meow!\n"; }23: };24:25: class Horse : public Mammal26: {27: public:
28: void speak() const { std::cout << "Whinny!\n"; }29: };30:31: class Pig : public Mammal32: {33: public:
34: void speak() const { std::cout << "Oink!\n"; }35: };
访问各类:
1: int main()
2: {3: Mammal* array[5];4: Mammal* ptr;5: int choice, i;
6: for (i = 0; i < 5; i++)
7: {8: std::cout << "(1) dog (2) cat (3) horse (4) pig: ";
9: std::cin >> choice;10: switch (choice)
11: {12: case 1:
13: ptr = new Dog;
14: break;
15: case 2:
16: ptr = new Cat;
17: break;
18: case 3:
19: ptr = new Horse;
20: break;
21: case 4:
22: ptr = new Pig;
23: break;
24: default:
25: ptr = new Mammal;
26: break;
27: }28: array[i] = ptr;29: }30: for (i=0; i < 5; i++)
31: {32: array[i]->speak();33: }34: return 0;
35: }
访问结果:
小结:
3.2多继承的情况
C既继承了A,也继承了B,类定义的代码如下:
1: #include <iostream>2: using namespace std;3: class A
4: {5: public:
6: A() { cout << "A construction" << endl; }
7: virtual ~A() { cout << "A destruction" << endl; }8: int a;
9: void fooA() {}
10: virtual void func(){ cout << "A func." << endl; };11: virtual void funcA() { cout << "funcA." << endl; }12: };13:14: class B
15: {16: public:
17: B() { cout << "B construction" << endl; }
18: virtual ~B() { cout << "B destruction" << endl; }19: int b;
20: void fooB() {}
21: virtual void func() { cout << "B func." << endl; };22: virtual void funcB() { cout << "funcB." << endl; }23: };24:25: class C : public A, public B26: {27: public:
28: C() { cout << "C construction" << endl; }
29: virtual ~C() { cout << "C destruction" << endl; }30: int c;
31: void fooC() {}
32: virtual void func() { cout << "C func." << endl; };33: virtual void funcC() { cout << "funcC." << endl; }34: };35:36: int main()
37: {38: A *pa = new A();
39: pa->func();40:41: B *pb = new B();
42: pb->func();43:44: C *pc = new C();
45: pc->func();46:47: A *pac = new C();
48: pac->func();49:50: system("pause");
51: return 0;
52: }
可以看到A,B,C三个类的构造函数和虚函数都不同,下面测试一下,创建对象以及调用虚函数时,派生类及父类的函数是如何执行的。
运行一下,观察结果:
分析小结:
4.总结
创建第一个虚函数时候就会创建一个v-table,包含虚函数成员的类必须维护v-table,因此会带来一些开销。如果类很小,并且不打算从它派生出其他类,就根本没必要使用虚函数。
C++中的虚函数解析[The explanation for virtual function of CPlusPlus]
标签:
原文地址:http://www.cnblogs.com/Steven-Love-Arlene/p/5154731.html