首先看代码,不采用虚函数的情况
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class A {
private:
int m_kk;
public:
A() {
m_kk = 100;
}
void print() {
cout << "this is A" << endl;
cout << m_kk << endl;
}
};
class B :public A {
public:
void print(){
cout << "this is B" << endl;
}
};
int main()
{
A a;
B b;
A* pa = &a;
A* pb = &b;
pa->print();
pb->print();
system("pause");
return 0;
}
上述的两次输出均为“this is A 100”。证明在不采用虚函数的基础上,用父类的指针指向子类,是指向子类中父类的一部分。其行为和父类相同。
下面是采用虚函数的情况
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class A {
private:
int m_kk;
public:
A() {
m_kk = 100;
}
virtual void print() {
cout << "this is A" << endl;
cout << m_kk << endl;
}
};
class B :public A {
public:
virtual void print(){
cout << "this is B" << endl;
}
};
int main()
{
A a;
B b;
A* pa = &a;
A* pb = &b;
pa->print();
pb->print();
system("pause");
return 0;
}
输出为this is A 100 this is B.证明父类指针指向子类对象时,调用虚函数是调用子类中的实现。下面对虚函数的实现机理做阐释:
如果一个类中存在虚函数,编译器会为该类创建一个虚函数地址表(vtbl),保存自己类中虚函数的地址。并为改建创建一个指针(vptr),指向这个表。每个类的对象都会有一个vptr,该类的所有对象公用一个vtbl。
当执行上面的pb->print()时,系统会先获取pb的vtbr,得到vtbl后进行分析后得出结果。
本文通过两个示例对比展示了C++中虚函数的作用及其实现机制。在没有使用虚函数的情况下,父类指针调用子类对象的行为如同直接操作父类;而在使用虚函数后,父类指针能正确调用子类覆盖的方法,体现了多态性。文章还解释了虚函数表(vtbl)的概念及其工作原理。

2431

被折叠的 条评论
为什么被折叠?



