读书人

请教?虚函数的存在必要是什么设计者

发布时间: 2013-10-14 12:54:46 作者: rapoo

请问?虚函数的存在必要是什么,设计者是出于怎样的考虑呢?


#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++ 虚函数 虚函数表
[解决办法]
class B : public A
{
}
class C : public A
{
}

A * pSubA1 = new B;
A * pSubA2 = new C;

这叫做多态,这叫做动态绑定,这叫做当你在写代码让一条鱼游泳的时候根本不用关心在运行时它是鲤鱼还是带鱼
[解决办法]
一个接口 多种实现 运行时类型确定调用哪个实现
[解决办法]
很有必要 把他的思想对应到现实生活中 你就更更明白
[解决办法]
引用:
Quote: 引用:

很有必要 把他的思想对应到现实生活中 你就更更明白
不懂,道友具体点。

简单举个例子
你家养了猫和狗
你说一句话"滚回去"
如果实现的时候是虚函数方式 是猫听到了 就滚回猫窝
狗听到了就会狗窝

但如果不是虚函数方式
猫狗听见了都不会理你 谁知道你叫谁滚回去啊?
除非你说猫滚回去 或者 狗滚回去 那么他们才执行自己的动作 但是你不觉得麻烦吗?

[解决办法]
你的描述, 可能是我的理解能力欠佳, 我是没有看明白.

"根本不会引起这样的问题" 什么样的问题? 我没有看明白.

"本身就是违反c++语义的行为" 我也没看到哪里有违反C++语义, 本身就是在应用C++中的动态绑定.

至于为什么要引和虚函数, 那肯定是为了多态撒, 如果没有虚函数或者类似虚函数的方式, 你还想到其它方式实现多态特性吗?
为什么叫虚函数, 我的理解是这样的: 因为你调用的时候这个函数还没有准确的定义, 是未知的,可以说叫还没有函数实体, 所以这个函数是虚的. 只有调用的时候才能知道其实体是什么.
[解决办法]
只有"调用"的时候才能知道其实体是什么. 应该是"执行"
[解决办法]
引用:
Quote: 引用:

一个接口 多种实现 运行时类型确定调用哪个实现

说实话,这个应该是初接触c++的人都懂的吧

我们就是觉得你其实没懂。
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

一个接口 多种实现 运行时类型确定调用哪个实现

说实话,这个应该是初接触c++的人都懂的吧

我们就是觉得你其实没懂。

没懂,那怎么写出最顶上的这代码的?你理解了我写着代码的意图么?

你只是写出了代码并且看到了结果而已。说出“本身就是违反c++语义的行为”这句话的时候我们自然以为你还没懂。虚函数就是C++语义,是有明确的设计目标的。你觉得“违反”是和你根据目前所学的知识,你觉得“违反”了,说明的正是你学的还没到位。
虚函数设计目标具体是什么,2L已经说了,1L 7L已经给出比喻了。你要做的是仔细阅读理解那些话,而不是来对着我冲。
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

很有必要 把他的思想对应到现实生活中 你就更更明白

不懂,道友具体点。

简单举个例子
你家养了猫和狗
你说一句话"滚回去"
如果实现的时候是虚函数方式 是猫听到了 就滚回猫窝
狗听到了就会狗窝

但如果不是虚函数方式
猫狗听见了都不会理你 谁知道你叫谁滚回去啊?
除非你说猫滚回去 或者 狗滚回去 那么他们才执行自己的动作 但是你不觉得麻烦吗?

其实调用的时候c.Print2();
前面的c已经是区分了猫和狗了。

虚函数的适用场合就是“在写代码的时候不知道是猫还是狗”
你这种写法本身就不该用虚函数,除了降低效率没有任何意义
你说多态耳熟能详?看来你也就只是耳熟而已
[解决办法]
类同“c++的优劣势”那贴,水贴一枚
[解决办法]
引用:
Quote: 引用:

一个接口 多种实现 运行时类型确定调用哪个实现

说实话,这个应该是初接触c++的人都懂的吧
懂不代表理解 我也没完全理解 就像我们都知道面向对象
[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

很有必要 把他的思想对应到现实生活中 你就更更明白
不懂,道友具体点。

简单举个例子
你家养了猫和狗
你说一句话"滚回去"
如果实现的时候是虚函数方式 是猫听到了 就滚回猫窝
狗听到了就会狗窝

但如果不是虚函数方式
猫狗听见了都不会理你 谁知道你叫谁滚回去啊?
除非你说猫滚回去 或者 狗滚回去 那么他们才执行自己的动作 但是你不觉得麻烦吗?

其实调用的时候c.Print2();
前面的c已经是区分了猫和狗了。

调用基类指针的时候!
[解决办法]
一个孩子问妈妈,我是从哪里来的?妈妈回答:别问傻话。
点评:
对于妈妈来说,这问题是傻话,但是对小孩子真不好解释。
对于孩子来说,这问题确实是困惑。但是长大后你自然就懂了。

结论:LZ你是孩子,长大自然懂得。
[解决办法]
引用:
所以我才会提出,没有虚函数功能照样运行,而虚拟函数表还要占内存。所以我很好奇什么时候才是真正该用虚函数的时候。

A * pSubA = NULL;
if( input() == 1 )
pSubA = new B;
else if( input() == 2 )
pSubA = new C;

pSubA->print();
return pSubA;

[解决办法]
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

很有必要 把他的思想对应到现实生活中 你就更更明白
不懂,道友具体点。

简单举个例子
你家养了猫和狗
你说一句话"滚回去"
如果实现的时候是虚函数方式 是猫听到了 就滚回猫窝
狗听到了就会狗窝

但如果不是虚函数方式
猫狗听见了都不会理你 谁知道你叫谁滚回去啊?
除非你说猫滚回去 或者 狗滚回去 那么他们才执行自己的动作 但是你不觉得麻烦吗?

其实调用的时候c.Print2();
前面的c已经是区分了猫和狗了。

调用基类指针的时候!

什么时候需要用基类的指针来访问子类的虚函数?

你知道子类有这么个方法 但是你运行之前并不确定到底是要使用哪个子类
[解决办法]
引用:
什么时候需要用基类的指针来访问子类的虚函数?

在程序执行之前只知道基类而不知道具体的子类,运行时具体是什么子类由运行情况和用户输入来决定
此时你只能使用基类的指针和引用来指定该对象的行为,具体什么对象执行什么样的行为必须在运行时确定对象的具体类型后才能绑定

读书人网 >C++

热点推荐