现在的位置: 首页 > 综合 > 正文

虚函数与虚函数表

2018年06月06日 ⁄ 综合 ⁄ 共 1316字 ⁄ 字号 评论关闭
 #include <afx.h>

struct A{
virtual void Print(){printf("A,Print\n");}
void Print2(){printf("A,Print2\n");}
};

struct B:public A{
void Print(){printf("B,Print\n");}
void Print2(){printf("B,Print2\n");}
};

struct C:public B{
void Print(){printf("C,Print\n");}
void Print2(){printf("C,Print2\n");}
};

int main()
{
A a;
B b;
C c;

A *pA1 = &a;//指向a

A *pB1 = &b;//指向b
B *pB2 = &b;

A *pC1 = &c;//指向c
B *pC2 = &c;
C *pC3 = &c;

printf("模块1:\n");
pA1->Print();//A,Print
pA1->Print2();//A,Print2

printf("\n模块2:\n");
pB1->Print();//B,Print
pB2->Print();//B,Print
printf("非虚函数:\n");
pB1->Print2();//A,Print2
pB2->Print2();//B,Print2
printf("\n模块3:\n");//
pC1->Print();//C,Print
pC2->Print();//C,Print
pC3->Print();//C,Print
printf("非虚函数:\n");
pC1->Print2();//A,Print2
pC2->Print2();//B,Print2
pC3->Print2();//C,Print2
printf("\n模块4:\n");
a.Print();//A,Print
b.Print();//B,Print
c.Print();//C,Print
printf("非虚函数:\n");
a.Print2();//A,Print2
b.Print2();//B,Print2
c.Print2();//C,Print2

system("pause");
return 1;
}

/*
子类有多个虚函数,所以需要引入虚函数表来管理调用的是哪个类的虚函数
(ps:有说法,类似于字符串为'\0'结尾,虚函数表中,虚函数结尾标示的是表中后面还有几个虚函数)。

子类调用虚函数时,根据类的类型访问类的虚函数表,
强转为父类时访问的就是父类的虚函数表,
然后在虚函数表中索引该虚函数。

模块2,模块3 可以很明显的看到
1 定义父类的指针,指向子类的变量。
2 使用该虚函数

那么问题来了,不定义使用的此函数为虚函数时,根本不会引起这样的问题(费力不讨好,虚函数表还占内存)。
因为这样做,本身就是违反c++语义的行为。引入虚函数,虚函数表到底出于什么考虑呢?

结论:
而析构函数不定义为虚函数一般也不会出错,
只要不出现以上2个蛋碎无语的情况。、
 
还是留下这个结论吧。
我笑自己当时太浅薄,蛋碎的情况确实存在而且广泛使用,就是父类指针指向子类函数的时候,
也就是当使用者不确定到底使用哪个对象的时候。
恰恰是吻合了c++的设计理念。
*/

抱歉!评论已关闭.