为什么说模板的是编译时多态性,而虚函数是运行时的。 我怎么觉得对函数的选择也是编译时刻的

cppprogramlover 2005-08-31 12:24:18
为什么说模板的是编译时多态性,而虚函数是运行时的。 我怎么觉得对函数的选择也是编译时刻的
...全文
517 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
好了,我回去看看书。谢谢
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
虚函数不是这样,为什么不能是这样?
junguo 2005-08-31
  • 打赏
  • 举报
回复
不是根据类型选择的,因为c++有一些命名规则!比如 class A{ void f()};那么你调用 A a; a.f();那么调用的伪代码可能是 call Af();而B类中的可能就是Bf。

而虚函数指针情况下不是这样,而变成了以上所说的虚函数表!
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
当用基类指针或引用调用虚函数时,结果是由运行时对象的类型决定的


--
你调用函数时候(不是定义,是调用),能给个例子不能决定对象的类型吗?
yayafu 2005-08-31
  • 打赏
  • 举报
回复
错,你这没有体现虚函数调用
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
void test(A *pBase)
{
pBase->f();
}
A *ptr;
//...

test(ptr);
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
谢谢 junguo。

我理解你的意思,事实上任何函数都是为了调用的。
class A{
//...
public:
virtual f(){/**/};
}
class B:public A{
//...
public:
f(){/**/};
}
当用不同的类型对象(A或B)去调用f()时,可以根据类型选择
A a;
B b;
a.f();
b.f();
SammyLan 2005-08-31
  • 打赏
  • 举报
回复
你回家慢慢睡觉吧
/zZ
yayafu 2005-08-31
  • 打赏
  • 举报
回复
虚函数只是一个函数指针表,具体调用哪个类的相关函数,要看运行是,对象指针或引用所指的真实类型,由于一个基类的指针或引用可以指向不同的派生类,所以,当用基类指针或引用调用虚函数时,结果是由运行时对象的类型决定的
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
使用虚函数保证了在通过一个基类类型的指针(包括引用)调用一个虚函数时,C++系统对该调用进行动态联编,但是,在通过一对象访问一虚函数时,使用静态联编。

为什么调用虚函数不进行静态联编。我觉得跟别的一样能行的啊。请指点一下。

书上可能我还没有看到后面的原因。
junguo 2005-08-31
  • 打赏
  • 举报
回复
举个简单的例子:
void test(CBase *pBase)
{
pBase->VirtualFun();
}

这段程序编译的时刻并不知道运行时刻要调用那个子类的函数,所以编译的时刻并不会选择跳转到那个函数去!如果不是虚函数,那么跳转的伪汇编代码应该是call VirtuallFun!但当是虚函数的时候,就不能这样了,而是变成了call pBase->虚函数表里的一个变量,不同的子类在这个变量含有不同的函数地址,这就是所谓的运行时刻了。但事实上 pBase->虚函数表里的一个变量 也是在编译时刻就产生的的,它是固定的。 所以运行时刻,还是编译时刻事实上也并不严密,重要的还是理解它的实质!
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
C++用函数重载和运算符重载来实现编译时的多态性。但是为什么虚函数通过继承来选择特定的函数不能通过编译时刻来选择。主要是这个问题。
cppprogramlover 2005-08-31
  • 打赏
  • 举报
回复
能说明白点么。 虚函数是怎么实现的。
我知道当然是我不对了,但是我看书上说的实现是用个数组,那样的话我觉得也能根据某某类的成员推断选择哪个函数啊。 就好比根据模板参数得到不同的函数代码一样。 可是这些都确实是编译时刻的。
yayafu 2005-08-31
  • 打赏
  • 举报
回复
因为你没有理解虚函数,没有学懂C++
junguo 2005-08-31
  • 打赏
  • 举报
回复
你需要得到对象的类型可以通过typeid来得到!
#include <iostream>
#include<vector>
#include <complex>
using namespace std;
class A
{
virtual void fun(){}
};
class B : public A
{
virtual void fun(){}
};

int main()
{

B *b = new B;

cout << typeid(b).name() <<endl;

system("pause");
return 1;
}

但在虚函数调用的时侯并不需要得到类型!因为你在定义的时候会在 (B b),对象b中生成一个虚函数表,它指向的就是B::fun,而A a,中的虚函数表的函数地址是指向A::fun,当通过A的对象调用的时候,是通过虚函数表中的地址来调用的,A和B中继承于A的虚函数表结构相同,只有指向的地址不同,当传输过来对象后,通过虚函数表来调用,就会调用不同的函数!

64,676

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧