对象如何调用类函数的问题

citywanderer2005 2006-07-11 09:49:10
假设有一个类
class Parent
{
public:
char data[20];
void Function1();
}parent;
sizeof(Parent)求出来的值是20,也就是说一个类的大小只包含了它的数据成员的大小(这里没有考虑vtable等别的东西),那么语句parent.Function1()中对象parent是如何找到函数Function1的入口地址的呢?
--------------------------------
另一个类似的问题:
class Parent
{
public:
char data[20];
void Function1();
virtual void Function2(); // 这里声明Function2是虚函数
}parent;
class Child:public Parent
{
void Function1();
void Function2();
}child;
main函数中
Parent *p;
p=&child;
p->Function1();
指针p为何调用的是Parent类中Funtion1函数而不是Child类中的函数呢?
...全文
753 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
pottichu 2006-07-11
  • 打赏
  • 举报
回复
没时间?
没时间就表做程序员了嘛!
做程序员是米有时间陪mm的。

citywanderer2005 2006-07-11
  • 打赏
  • 举报
回复
现在写一篇关于j2ee项目方面的论文,实习的工作又是做C#.net的项目,自己的兴趣是C++,还正在追一个mm。我都快疯了,哪里有时间看《inside c++ object model》啊!
KenYuan2016 2006-07-11
  • 打赏
  • 举报
回复
这个是类的多态性上面的.
Parent *p=new Child;
我们可以通过虚函数实现多态.
在Parent中已经定义的是一个实现函数void Function1();而不是需函数。
这是调用的时候调用的是Parent的东西。需函数则调用的是Child实现的函数,而且Child必须实现该函数。
OOPhaisky 2006-07-11
  • 打赏
  • 举报
回复
哈哈,建议楼主看看《inside c++ object model》,里面一定有很多吸引你的东西。
但是看的时候最好搭配英文原版看,有些地方侯捷翻译的不太好,总之看这本书时,不要太相信侯捷,要相信Lippman,经验之谈......
bing_huo 2006-07-11
  • 打赏
  • 举报
回复
Funtion1 函数不是 virtual 属性的,
没有多态,
指针类型决定了调用的函数属于哪个类 ...



补充下:非virtual函数 指针的静态类型决定调用哪个函数
virtual函数 指针的动态类型决定调用哪个函数

Parent *p = new Child;

指针p的静态类型是Parent 动态类型是Child
jixingzhong 2006-07-11
  • 打赏
  • 举报
回复
不要忘了有一个隐含的 this 指针 ...

楼主可以看看 <inside c++ object model> ,
对类的构成可以有一个比较深刻的理解 ...



指针p为何调用的是Parent类中Funtion1函数而不是Child类中的函数呢?
=================================
Funtion1 函数不是 virtual 属性的,
没有多态,
指针类型决定了调用的函数属于哪个类 ...
citywanderer2005 2006-07-11
  • 打赏
  • 举报
回复
<inside c++ object model>,嗯,有时间看看去
citywanderer2005 2006-07-11
  • 打赏
  • 举报
回复
sinall说的“普通成员函数调用(非virtual函数),是根据指针类型确定的。”,想问一下你是如何知道的?
pottichu 2006-07-11
  • 打赏
  • 举报
回复
如上面各为大虾所说,去看看 <inside c++ object model>吧。
有详尽的解释。
triace_zhang 2006-07-11
  • 打赏
  • 举报
回复
1.编译器对类函数自动增加一个隐含参数 this指针,比如你例子里的void Function1();
它的地址在函数表而不是在类体里,在函数表里它的完全表示是:
void Parent::Function1( Parent *this ); //this为隐含参数
调用的时候你的代码是:
parent.Function1(); 编译器自动扩展代码为:
parent.Function1(&parent); 即把调用该函数的类实例的地址作为隐含参数传给类函数,这样类函数就可以通过隐含参数this指针访问实际调用它的类实例了。比如Function1()里面
可以
void Function1(){
cout << data; // 实际编译器自动扩展为cout << this->data;
}

那么调用时候parent.Function1(); 扩展为parent.Function1(&parent);
this指针指向parent实例,this->data就是(&parent)->data

2.这个是多态和虚函数的问题。可以找c++的书看一下比较清楚。
基本上就是Function2是基类的虚函数,虚函数的地址是要从虚函数表里找
lyskyly 2006-07-11
  • 打赏
  • 举报
回复
Parent *p;
p=&child;
p->Function1();
这里它是根据p的类型来判断调用Parent_Function1(Parent* pThis)
而不是Child_Function1(Child* pThis)
如果是虚函数,就不一样了,它更加虚函数表查询调用的函数的地址
bing_huo 2006-07-11
  • 打赏
  • 举报
回复
简单的说 编译器把函数放在一个单独的代码段 不管是哪个类的 而且 每个函数只有一份 编译器当然就知道在哪了

而virtual函数 是 c++语言 oo机制的核心部分 通过给每个类增加一个vtbl 并且 对象包含一个指向这个vtbl的指针 vptr 达到运行期决定执行哪个函数的目的

这个话题太大了 建议楼主去读一下 <inside c++ object model>
sinall 2006-07-11
  • 打赏
  • 举报
回复
parent.Function1()
第一个参数是this指针,类似于Parent::Function1(this),
所以“对象parent是如何找到函数Function1的入口地址”应该是“Function1知道parent的地址”。

普通成员函数调用(非virtual函数),是根据指针类型确定的。
lyskyly 2006-07-11
  • 打赏
  • 举报
回复

void Function1();
其实你可以把它看成一个全局函数 Parent_Function1(Parent* pThis)
parent.Function1()这个调用实际上只是相当于Parent_Function1(&parent)

64,688

社区成员

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

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