简单情况:

#include<iostream>
using namespace std;
class A
{
public:
virtual void foo()
{
cout << "virtual void foo()" << endl;
}
}; int main()
{
//通过对象调用,会当成普通成员函数来看待。
A a;
a.foo();
cout << "---------------------" << endl;
A *b = new A();
b->foo();
//编译器视角
/*
((*(b->vptr))[0])();
通过虚函数表指针调用
*/
while (1);
return 0;
}

总结:

1.如果通过对象调用虚函数,编译器直接找到虚函数的地址。

2.对于虚函数和成员函数,编译器都会隐式的传入this指针。

3.对于指针和引用的形式来调用虚函数,编译器走的则是虚函数表的路线。

4.无论是成员函数还是虚函数,他的地址都是在编译期间就已经确定下来了,接下来就看你怎么去找到这个虚函数的地址,可以直接找,也可以通过虚函数表.

复杂情况以及静态成员函数的调用形式:

#include<iostream>
using namespace std;
class A
{
public:
virtual void foo()
{
cout << "virtual void foo()" << endl;
//foo2();//如果虚函数里面这么调用还是会通过虚函数表找到虚函数的地址,所以为了效率,通过类调用(因为在函数内部,所以接下来通过类调用这个this指针编译器可以找的到)
/*
既然在外部已经进入到该虚函数内部了,说明该对象是生成了的,也就是这个this指针存在了
所以接下来的A::foo2();调用会成功,如果在main函数中直接调用A::foo1(),肯定失败,因为编译器隐式传进去的形参this根本就找不到
*/
A::foo2();
}
virtual void foo1()
{
cout << "virtual void foo1()" << endl;
}
static void foo2()
{
cout << "virtual void foo2()" << endl;
}
void aa()
{
cout << "fds" << endl;
}
int data = 3;
};
int main()
{
//如果想让非成员函数像静态成员函数一样被调用。
((A*)0)->aa();//前提是函数体中不能用到隐式传进去的0指针。
/*
对于成员函数aa(),编译器会隐式的传进去0指针,这个0指针实际上里面并没有保存类A的内容,作用仅仅是用来调用该成员函数,类似于:A*p;
p->aa();只是用了一种诡异的手法将这两步进行合并,再调用。
不管是0还是其他的地址,都无所谓,只要用不到那个指针就行,比如 ((A*)899980)->aa();同样也能正常运行,因为前面那个地址仅仅是生成A类型的指针。
如果写成cout<<((A*)0)->data来打印里面的数据成员就错了,因为0地址里面实际并没有保存真正的类A的内容。
*/ //对于静态的成员函数,它不依赖于类对象,所以编译器并不会给他隐式的传进去this指针。
//所以可以直接用类成面来调用。
A::foo2(); //对于虚函数,通过对象调用相当于普通成员函数的调用,用指针和用引用调用则是通过虚函数表来找到对应的虚函数。
/*A ss;
//ss.foo(); cout<<"通过虚函数表找到虚函数的地址"<<endl;
A&p = ss;
p.foo(); A*p=new A();
p->foo(); A&cc = *p;
cc.foo();
*/ /*
普通的成员函数和虚函数在调用的时候编译器都会隐式的传入this指针,而对于静态函数则例外。
*/ while (1);
return 0;
}

最新文章

  1. Bootstrap3-技巧之解决Bootstrap模态框切换时页面抖动 or页面滚动条
  2. Windows下用Codeblocks建立一个最简单的DLL动态链接库
  3. linux 双网卡实现
  4. div背景图片叠加
  5. MVC 3个重要的描述对象之ControllerDescriptor
  6. NYOJ-235 zb的生日 AC 分类: NYOJ 2013-12-30 23:10 183人阅读 评论(0) 收藏
  7. Semaphore — Windows API
  8. Velocity入门系列
  9. 0721JS
  10. BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)
  11. OpenCV3计算机视觉Python语言实现笔记(五)
  12. [iOS]视图与UIVIew
  13. 面向对象的类关系及其C++实现
  14. Jmeter(GUI模式)教程
  15. L1 与 L2 正则化
  16. Firefox不支持event解决方法
  17. linux开启远程访问端口
  18. 20155303 2016-2017-2 《Java程序设计》第七周学习总结
  19. CCoolBar 的替代方案 CDockablePane。
  20. java学习笔记_多态

热门文章

  1. 隐藏计划任务反弹shell
  2. SpringBoot使用 MyBatis Plus 实现物理分页查询
  3. spoj - ACTIV - Activities
  4. rsync 守护进程及实时同步
  5. [开发配置]Linux系统配置开发环境
  6. Window/Linux下Mysql的安装步骤
  7. 了解C#的协变和逆变
  8. Nginx-正反向代理及负载均衡
  9. hive 之 将excel数据导入hive中 : excel 转 txt
  10. centos7 重定向符号