鱼C论坛

 找回密码
 立即注册
查看: 93|回复: 5

[技术交流] C++类中成员函数的调用

[复制链接]
发表于 2024-8-3 13:05:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
类可以看做是一种复杂的数据类型。类是创建对象的模板,不占用内存空间,不存在于编译后的可执行文件中;而对象是实实在在的数据,需要内存来存储。对象被创建时会在栈区或者堆区分配内存。

编译器会将成员变量和成员函数分开存储:分别为每个对象的成员变量分配内存,但是所有对象都共享同一段函数代码。成员变量在堆区或栈区分配内存,成员函数在代码区分配内存。对象的大小只受成员变量的影响,和成员函数没有关系。成员函数最终被编译成与对象无关的全局函数。


那么,如果成员函数中使用到了成员变量该怎么办呢?成员变量的作用域不是全局,不经任何处理就无法在函数内部访问。


C++规定,编译成员函数时要额外添加一个参数,把当前对象的指针传递进去,通过指针来访问成员变量。






这样通过传递对象指针就完成了成员函数和成员变量的关联。这与我们从表明上看到的刚好相反,通过对象调用成员函数时,不是通过对象找函数,而是通过函数找对象。

这一切都是隐式完成的,对程序员来说完全透明,就好像这个额外的参数不存在一样。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2024-8-3 13:09:18 | 显示全部楼层
本帖最后由 行客 于 2024-8-3 13:15 编辑
FishC 发表于 2024-8-3 13:06
哈哈,真是一番深奥又富有哲理的解释!来,我给你再用一种幽默的方式简化一下这个复杂的知识点。

想象一 ...

可以简化为以下几步:
1.
对象实例化时,为成员变量分配内存。(注意不包括成员函数)
2.
调用对象的成员函数时,编译器自动将对象的地址作为隐藏参数传递给函数。
调用对象的成员函数时,实际调用的是编译后的全局的一个普通函数,只是调用时默认隐式传入了一个参数,就是将对象的地址传入了。编译后类似:
  • void new_function_name(Demo * const p){
  •     //通过指针p来访问a、b
  •     cout<<p->a<<endl;
  •     cout<<p->b<<endl;
  • }
3.
成员函数内部,通过"this"指针(上例中的"p")访问到该对象的成员变量,实现数据操作。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-3 13:06:03 | 显示全部楼层
哈哈,真是一番深奥又富有哲理的解释!来,我给你再用一种幽默的方式简化一下这个复杂的知识点。

想象一下,C++类就像一个厨师的食谱书,其中包含了各种各样的菜肴(也就是成员函数)。不过,这个食谱本身不占用多大地方,毕竟只是纸上写的东西,对吧?而当你要做菜的时候,你需要准备真正的食材(也就是对象),而这些食材可是真金白银,需要在厨房里占用空间。

在这个厨房里,每当你决定做某道菜(调用成员函数)的时候,其实是通过“厨师”的手来完成的。不过,奇怪的是,虽然菜谱上写了做法,实际操作的时候,厨师总是需要你提供食材的指引——这就像程序中,成员函数在执行时需要一个“隐形助手”指向当前对象。

这个“隐形助手”就是那个额外传递的指针,它悄悄地告诉函数:“嘿,伙计,我现在是在哪个对象上的啊!”所以,虽然你是通过对象来调用成员函数,但在背后,它其实是在通过成员函数找到相关的对象,仿佛是在说:“我知道你在哪里,但是我要请你帮我找我的食材!”

总之,C++中成员函数和成员变量的关系就像厨师和食材之间的互动,虽看似复杂,实则内部运作非常顺畅。就像我们的生活一样,有时候默默付出的那位“隐形助手”,才是让一切顺利进行的关键!希望这个比喻能帮助你更好地理解C++啦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-3 13:11:30 | 显示全部楼层
行客 发表于 2024-08-03 13:09
可以简化为以下几步:
1.
对象实例化时,为成员变 ...


非常棒的简化步骤!我们来给这三步添加一点幽默,让它更容易记住。

1. **对象实例化时,为成员变量分配内存。**  
   想象一下,当你为一个新房子准备好家具(成员变量)的时候,建筑工人(编译器)会把这些家具放到特定的地方。房子的空间是你的,而家具则是在里面的。

2. **调用对象的成员函数时,编译器自动将对象的地址作为隐藏参数传递给函数。**  
   当你决定邀请朋友(成员函数)来家里聚会时,你需要给他地址,但聪明的编译器已经偷偷帮你做好了这件事——他悄悄地把地址给了你的朋友(通过“隐形助手”)。你的朋友只需知道往哪个方向走就可以了。

3. **成员函数内部,通过"this"指针访问到该对象的成员变量,实现数据操作。**  
   现在,朋友到了现场,他一进门就看到你为他准备的家具。他拿起东西(成员变量),就像通过“this”指针一样,随意地享受“你家”的一切。这个“this”指针就像是一张特别的VIP通行证,让他可以自由访问你所提供的一切!

通过这个幽默的比喻,希望你能更轻松愉快地记住 C++ 中成员函数和成员变量之间的关系!如果还有其他问题,随时问我哦!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-8-3 13:20:17 | 显示全部楼层
FishC 发表于 2024-8-3 13:06
哈哈,真是一番深奥又富有哲理的解释!来,我给你再用一种幽默的方式简化一下这个复杂的知识点。

想象一 ...

这个解释不太友好,不容易理解。修改的更通俗易懂、准确一些。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-8-3 13:20:26 | 显示全部楼层
行客 发表于 2024-08-03 13:20
这个解释不太友好,不容易理解。修改的更通俗易懂、准 ...


当然可以!让我们用更简单直接的方式来解释C++中成员函数和成员变量的关系。

1. **对象实例化时,为成员变量分配内存。**  
   当你创建一个对象(比如用`Demo demo;`),编译器会为这个对象的所有成员变量分配内存。这就像是给这个对象准备了一份“内部清单”,但是成员函数不占空间,因为它们只是可以被调用的规则。

2. **调用对象的成员函数时,编译器自动将对象的地址作为隐藏参数传递给函数。**  
   当你调用一个成员函数(比如`demo.memberFunction()`),编译器会悄悄地把当前对象的地址传递给这个函数。这意味着函数内部可以知道自己正在操作的是哪个对象,即使你并没有显示地传递这个地址。

3. **编译后的实际形式**  
   编译器会将`demo.memberFunction()` 转换成如下形式:
new_function_name(&demo);
   这段代码表示编译器实际上调用的是一个普通的函数,并把对象的地址(`&demo`)作为参数传递给它。这样,函数就可以通过这个地址访问成员变量了。

总结一下:在C++中,当你调用对象的方法时,编译器不仅会找到相应的函数,还会偷偷把对象的地址传进去。这样,函数就可以直接访问和操作该对象的成员变量了。

希望这个解释能让你更清晰地理解成员函数和成员变量之间的关系!如果还有其他问题,随时告诉我!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-21 11:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表