当前位置: 首页 > news >正文

第4章 Function 语意学1: Member的各种调用方式

一、Nonstatic member functions

C++ 的设计准则之一就是:nonstatic member function 至少必须和一般的nonmember function 有相同的效率。也就是说,如果我们要在以下两个函数之间作选择:

float magnitude3d( const Point3d * this ) { ... }
float Point3d::magnitude3d() const { ... }

那么选择 member function 不应该带来什么额外负担。这是因为编译器内部已将member 函数实体”转换为对等的“nonmember 函数实体。转化步骤:

1.引入形参this

// non-const nonstatic member 之增长过程Point3d
Point3d::magnitude( Point3d *const this )

2.对nonstatic data member 的存取操作改成经由this

return sqrt(
    this->_x * this->_x + 
    this->_y * this->_y + 
    this->_z * this->_z);

3.将此member function 通过 mangling 改名

extern magnitude_7Point3dFv(register Point3d *const this );

现在这个函数已经被转换好了,而其每一个调用操作也都必须转换。于是:

obj .magnitude () ;
// 变成了:
magnitude_7point3dFv( &obj );

二、Virtual member functions

如果 normalize()是一个 virtual member function,那么以下的调用将会被内部转化为:

ptr->normalize();
// 
( * ptr->vptr[ 1 ])( ptr );

其中:

  • vptr 表示由编译器产生的指针,指向 virtual table,它被安插在每一个“声明有(或继承自)一个或多个 virtual functions”的 class object 中。

  • 1 是 virtual table slot 的索引值,关联到 normalize()函数。

  • 第二个 ptr 表示 this 指针。

对于以下调用:

// Point3d obj;
obj.normalize();

如果编译器把它转换为:

( * obj->vptr[ 1 ])( &obj );

可以,却没有必要。应该像对待nonstatic member function 一样加以决议:

normalize_7Point3dFv( &obj );

三、Static Member Functions

编译器处理起来就和一个nonmember function一样

然后简单介绍了为什么会出现Static Member Functions。

首先,对于member data的存取,编译器需要走this指针;

其次, static 数据不是存放在类对象中,所以存取数据可以不走 this 指针;

而 static 一般建议使用 nopublic 的方式来声明,并通过一些public的function来存取,这样我们可以避免对象的生成,直接通过类静态函数进行访问。所以会出现下面这种存取方式:

(( Point3d* ) 0 )->object_count();

至于语言层面上的解决之道,是由 cfront 2.0所引人的 static memberfunctions。Static member functions 的主要特性就是它没有 this 指针。以下的次要特性统统根源于其主要特性:

  • 它不能够直接存取其 class 中的 nonstatic members.

  • 它不能够被声明为 const、volatile 或 virtual。

  • 它不需要经由 class obiect 才被调用---虽然大部分时候它是这样被调用的!

如果取一个 static member function 的地址,获得的将是其在内存中的位置也就是其地址。由于 static member function 没有 this 指针,所以其地址的类型并不是一个“指向 class member function 的指针”,而是一个“nonmember 函数指针”。也就是说:

&Point3d::object count();
会得到一个数值,类型是:
unsigned int (*)();
而不是:
unsigned int ( Point3d::* )();

相关文章:

  • nginx配置反向代理服务器,实现在https网站中请求http资源
  • Redis数据结构,渐进式遍历,数据库管理
  • Ubuntu20.04本地配置IsaacGym Preview 4的G1训练环境(二):训练与推理
  • [Java基础-线程篇]7_线程设计模式与总结
  • MCU-SDRAM-W9825G6KH的存储单元
  • Vue 文件下载功能的跨域处理与前后端实现详解
  • python: DDD using postgeSQL and SQL Server
  • 【STM32】STM32系列产品以及新手入门的STM32F103
  • 深度学习PyTorch之13种模型精度评估公式及调用方法
  • 头歌作业-数据库实验一:数据库和数据表的建立,修改和删除
  • 大模型——使用 Embedding 模型和向量数据库的 Spring AI RAG
  • Linux下磁盘读写流
  • 《几何原本》命题I.12
  • API和SDK
  • 护照阅读器在汽车客运站流程中的应用
  • Excel表格打印 第二页边框隔断
  • 在Spring Boot + MyBatis中优雅处理多表数据清洗:基于XML的配置化方案
  • Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(5)
  • #如何改变怂怂懦弱的气质(2)
  • 【Linux内核系列】:进入文件系统的世界
  • 组建个人网站/最近国家新闻
  • 做logo的著名网站/知名seo公司
  • 自己开加工厂怎么找订单/石家庄百度推广优化排名
  • 1688做网站费用/个人网站备案
  • 社区网站建设/公司网页网站建设
  • 海关申报网站怎么做/品牌推广策略怎么写