认清C++语言之《成员函数查找》

C++必知必会之(24)成员函数查找 1、调用一个成员函数时,包括三个步骤: 第一步,编译器查找函数的名字; 第二步,从可用候选者中选择最佳匹配函数; 第三步,检查是否具有访问该匹配函数的权限。 2、很多与函数匹配有关的错误并非源于对编译器复杂的名字查找和重载函数匹配算法的误解,而是对这有序三大步的性质的误解。 class B  {      public:          //..... 阅读详情

成员函数查找:

1)  调用一个成员函数时,涉及三个步骤:一是编译器查找函数的名字;二是从可用候选者中选择最佳匹配函数;三是检查是否具有访问该匹配函数的权限。例如:

class App

{

public:

//........

void find(double);

};

 

class ACEApp : public App

{

void find(int);

};

 

//..........

ACEApp aa;

aa.find(13.4);                     //容易混淆

 

上面代码调用的是哪一个成员find?分析如下:

步骤一:查找函数名字。从ACEApp的作用域开始查找并且立即定位到ACEApp::find上。

步骤二:从可用候选者中选择最佳匹配函数。因为我们只有一个候选者,因此会尝试匹配该函数,通过将实参13.4从double转换为int做到这一点。

步骤三:检查访问权限。我们可能得到一个错误,因为ACEApp::find是私有成员。

 

匹配的过程中,编译器一旦在内层作用域中找到一个,它就不会到外层作用域中继续查找该名字。内层作用域的名字会隐藏外层作用域中相同的名字。这一点和Java不同,因为在Java中,内层作用域中的方法名字和外层作用域中同名方法属于重载关系。

 

实际上,该名字甚至可以不是一个函数的名字:

class HWApp : public ACEApp

{

    int f;

};

//..........

HWApp ha;

ha.f(12);                        //Err!

 

 

实参相依的查找:

1)  实参相依的查找(Argument Dependent Lookup,ADL):当查找一个函数调用表达式中的函数名字时,编译器也会到“包含函数调用实参的类型”的名字空间中检查。例如:

namespace ACE

{

class Hw {.....};

void find(const Hw &);

Hw operator +(const Hw &, const Hw &);

class String {....};

std::ostream operator <<(std::ostream &, const String &);

};

//......

void AceFunc()

{

ACE::Hw hw;

find(hw);                                     //调用ACE::find

hw = hw + hw;     //调用ACE::operator +

}

 

普通的查找是不会发现函数ACE::find的,因为它嵌套在一个名字空间内,并且对find的使用需要以该名字空间的名字加以限定。然而,由于实参hw的类型被定义于ACE名字空间中,因此,编译器也会到该名字空间中检查候选函数。

2) 实际上,很多程序员广泛地使用了ADL却没意识到这一点,例如:

ACE::String name("hw");

std::out <<"Hello, "<<name;

在这个例子中,对operator<<的第一个使用极可能调用的是类模板std::basic_ostream的一个成员函数,而第二个则是对位于ACE名字空间中重载的operator<<的非成员函数的调用。

 

 

操作符函数查找:

1)  有时看上去好像一个成员操作符函数重载了一个非成员的操作符,事实上并非如此,这不是重载,而是不同的查找算法。例如下面的类,它以成员函数的形式重载了一个操作符函数:

class ACEClass

{

public:

ACEClass operator %(const ACEClass &) const;  //二元取余操作符

ACEClass memFunc1(const ACEClass &);

void memFunc2();

//.......

};

 

可以采用中缀或函数调用语法来调用这个重载的操作符函数:

ACEClass aa, ab, ac;

aa = ab % ac;             //采用中缀语法调用成员操作符%

aa = ab.operator%(ac);  //成员函数调用语法

aa = ab.memFunc1(ac);   //另一个成员函数调用

当我们使用函数调用语法时,应用的是普通的函数查找规则,即对ab.operator%(ac)调用的处理方式与memFunc1的相同。而对于中缀操作符调用来说,编译器不仅会考虑成员操作符,也会考虑非成员操作符:

ACEClass operator %(const ACEClass &, int ); //非成员操作符

//.........

void ACEClass::memFunc2()

{

*this % 12;              //调用非成员操作符%

operator %(*this, 12); //错误,实参太多

}

 

对于中缀操作符调用来说,编译器不仅会考虑成员操作符,也会考虑非成员操作符,上面代码中第一个对operator%的中缀调用,将会匹配非成员的那一个。注意:这不是函数重载的实例,而是编译器在两个不同地方查找候选函数。

C++语法分析器tree-sitter-cpp:轻量级代码解析与编辑器集成实战 语法分析器是编译原理中的核心组件,负责将源代码字符流转换为结构化的语法树,为代码理解、高亮和静态分析提供基础。其工作原理基于形式语言与自动机理论,通过词法分析和语法分析构建程序的结构化表示。在工程实践中,语法分析器的技术价值在于实现代码的自动化处理,如智能补全、错误检测和重构工具。应用场景广泛覆盖IDE开发、代码质量检查和文档生成等领域。本文聚焦于tree-sitter-cpp这一轻量级C++语法分析器,它采用增量解析和声明式语法定义,高效处理C++的模板和预处理器等复杂特性,并支持查询语言进行精准的节点提 阅读详情

相关推荐

Kettle安装与使用

Pentaho Data Integration作为一个端对端的数据集成平台,可以对多种数据源进行抽取(Extraction)、加载(Loading)、数据落湖(Data Lake Injection)、对数据进行各种清洗(Cleasing)、转换(Transformation)、混合(Blending),并支持多维联机分析处理(OLAP)和数据挖掘(Data mining)。勺子(spoon.bat/spoon.sh):是一个图形化的界面,可以让我们用图形化的方式开发转换和作业。

jnrjian的博客 1万+

C++ find():泛型算法和成员函数

一、泛型算法: 泛型算法是STL库里面定义的一些算法,这些算法可以用一个接口操作各种数据类型,因此成为泛型算法。大多算法定义在头文件algorithm和numeric中。 find的前两个参数是表示元素范围的迭代器,第三个数是一个值,find将范围中的每个元素与给定的值进行比较,如果有匹配元素,则返回第一个等于给定值的元素的迭代器,如果无匹配值,则返回find中第二个用来表示范围的迭代器参数来表示搜索失败。 代码: #include <iostream> #include <ve

liu_feng_zi_的专栏 777

[零基础]用docker搭建Hadoop集群

[零基础]用docker搭建Hadoop集群,每一步都有详细的解释!

weixin_56114243的博客 2万+

还在为没有对象发愁?C++教你如何创建对象(上)

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。 这样说还是太抽象了,举个例子 比如要设计一个教务管理系统 面向过程:关注成绩查询、选课、课表查询等这些过程。体现到代码层面---方法/函数 面向对象:关注实现类对象及类对象间的关系,学生、教师以及他们之间的关系。体现到代码层面--类的设计及类之间的关系。 C++基于面向对象:面向过程和面向对象混编。

qq_52363432的博客 2179

数字后端零基础入门系列 | Innovus零基础LAB学习Day9

数字后端零基础入门系列 | Innovus零基础LAB学习Day9

weixin_37584728的博客 4577

ESP32 CAM安装配置 第四部份:通过使用ESPHome的方式ESP32 Cam加到HomeAssistant

这些包括 aec_value, aec2, ae_level, agc_gain, gain_ctrl, bpc, wpc, raw_gma, lenc, hmirror, dcw, colorbar 等。这些参数的可能值和具体效果会根据你的摄像头硬件和 ESPHome 的版本有所不同。在 ESPHome 中配置 ESP32 Cam 时,每个参数的可能值取决于具体的功能和支持范围。值的范围是 0 到 63,其中 0 是最差质量,63 是最佳质量。horizontal: 水平校正的强度,通常是一个数字值。

weixin_42895252的博客 3364

【C++学习】类和对象 | 类的成员函数存放在哪里?| this指针 | 构造函数 | 析构函数 | 探索构造和析构函数的更多细节

类和对象 | 类的成员函数存放在哪里?| this指针 | 构造函数 | 析构函数 | 探索构造和析构函数的更多细节

Locky136的博客 2813

【第六届起重机创意大赛国一作品——资料分享】

文章目录前言一、比赛内容分析二、确定方案与作品模型1.方案简图2.作品模型三、电控部分控制思路单片机选择与资源分配拓展板的设计接线与走线代码分享总结

qq_19308801的博客 7781

认清C++语言之《模板特化specialization》

模板:1)  区分模板参数(template parameter)和模板实参(template argument),前者用于模板的声明,后者用于模板的特化中:templatetypename T>                //T是一个模板参数class Heap {.....};//........Heapdouble> dHeap;                 //

ASCE1885 2028

学术类PPT制作总结

本文分享了科技类PPT的制作技巧,希望相关的信息能帮助到读者。

奇妙水果的技术博客,欢迎交流技术~ 2881

1688店铺所有商品API接口(整店商品查询API接口)

1688店铺所有商品API接口、1688店铺列表API接口,1688店铺API接口,1688店铺查询商品API接口,1688店铺商品API接口,1688店铺详情接口,1688商品API接口

tbprice的博客 1568

《认清C++语言》のstd::stringstream和strstr

1)std::stringstream的定义如下: typedef basic_stringstream&lt;char&gt; stringstream; 它是basic_stringstream模板在char类型上的一个特化,使用该类型需要包含头文件&lt;sstream&gt;.   std::stringstream经常被用来将字符串和各种基本数据类型之间进行转换,功能类似于C标准...

weixin_33998125的博客 101

PCL 点云圆柱形邻域搜索【2026最新版】

圆柱形邻域搜索是KD-tree算法在点云数据处理中的扩展应用,在一些特定场景应用中具有无与伦比的优势。博客长期更新,本文最近一次更新时间为:2026年5月4日。

点云侠的博客 3450

《认清C++语言》---类型转换和多级指针

类型转换:1、  C风格的类型转换不尽如人意:1)很粗鲁,我们可以通过它们在任意类型之间进行转换;2)该类型转换很难进行查找。2、 C++通过引入4种新的类型转换操作符克服了C风格的类型转换的缺点:static_cast、const_cast、dynamic_cast、reinterpret_cast。有了这些操作符,以前习惯的写法:(type)expression;现在通常写

ASCE1885 1665

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C++ 特性使用建议

使用引用替代指针且所有不变的引用参数必须加上const。在C 语言中,如果函数需要修改变量的值,参数必须为指针,如,在 C++ 中,函数还可以声明引用参数,定义引用参数防止出现 (*pval)++ 这样丑陋的代码。像拷贝构造函数这样的应用也是必需的,而且更明确,不接受 NULL 指针。建议:只在定义移动构造函数与移动赋值操作时使用右值引用,区分std::move与std::forward的作用。右值引用是一种只能绑定到临时对象的引用的一种,其语法与传统的引用语法相似,例如声明了一个其参数是一个字符串的右值引

Doublelv 的博客专栏。 1401

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

国嵌c语言深度,国嵌C语言3部全

课程目录:国嵌 C语言深度剖析班:1课-基本数据类型分析2 auto,register,static分析3 if,switch,do,while,for分析4 goto,void,extern,sizeof分析5 const和volatile分析6 struct和union分析7课-enum和typedef分析8 注释符号9 接续符和转义符10 单引号和双引号11 逻辑运算符使用分析12 位运算符...

weixin_42123237的博客 314

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C语言基础

C语言为什么是高效的?   C语言是底层机器上的高级抽象,以至于让大部分低级语言没有意义。既可以用来编写高级算法,也可以用来处理底层硬件逻辑。   C语言是一种弱类型语言,所有调用函数的参数类型和返回值类型必须被明确定义;这样做的缺点就是调用者的自由度有限,缺点的同时也是优点,可以让人少犯错误,c语言尽力构建一个简洁的、通俗的类型系统,不需要考虑太多依赖关系,使开发变得简单。   C语言不隐...

weixin_33755554的博客 134

卡尔曼滤波从原理到工程实践:公式、调参与避坑指南

在工程实践中,噪声和不确定性无处不在,传感器数据难以直接信任,如何从观测中提取真实状态成为关键问题。卡尔曼滤波作为一种经典的最优状态估计算法,通过预测与更新两个步骤,动态权衡模型预测与观测数据,实现了对系统状态的精准估计。其核心在于用协方差矩阵量化不确定性,并利用卡尔曼增益实现最优融合,因此在传感器融合、惯性导航、目标跟踪等场景中广泛应用。本文从一维温度估计到多维车辆跟踪,逐步推导五个核心公式,并结合代码实现与调参经验,同时介绍了扩展卡尔曼滤波和无迹卡尔曼滤波在非线性系统中的运用,最后总结了工程落地的常见坑

weixin_34265814的博客 366
上一篇: 《认清C++语言》---new and delete
下一篇: 认清C++语言之《函数指针》
ACE1985
博客等级 码龄17年 1307粉丝 308原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值