`
yesjavame
  • 浏览: 687260 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

用 (*it).m 还是 it->m

阅读更多
用 (*it).m 还是 it->m

摘自《Extended STL》

标准库要求,所有值类型为聚合类型的迭代器必须支持指针成员选取运算符(operator ->()),下面是使用该运算符的示例代码:

struct X
{
int x;
};

some_iterator<X> si = . . .
some_iterator<X> si2 = . . .
some_iterator<X> end = . . .

if( end != si &&
end != si2)
{
si->x = si2->x;
}

标准(C++-03: 24.1.1;1)要求,对一个迭代器应用指针成员选取运算符,在语义上等同于先对其应用解引用运算符,再应用点号成员选取运算符,即it->m与(*it).m等效。

可惜,使用该运算符会遇上麻烦。

假设我们有一个容器类型C,它的实例保存智能指针类型P的实例,P用于管理对象生存期。P上定义了一个release()方法用于提早释放对象。进一步假设,被P管理的类型T上也定义了一个release()方法。在下面代码片断中,我们希望通过该容器的迭代器类型I的一个实例,调用T::release()方法:

C cont = . . .
I it = cont.begin();
it->release();

不幸的是,这段代码调用的不是T::release()方法,它调用的是P::release()方法,从而销毁了T的实例。当我们再次使用cont这个容器的时候,就可能遇到各种奇怪的问题,以下代码才是真正实现我们想法的代码:

C cont = . . .
I it = cont.begin();
it->->release();

可是C++并不支持这样的语句,且理由充分。(想象一下,如果C++支持这样的语句,"模糊C++代码"大赛上,会有多少参赛代码,争着在一条语句中塞进最多的operator->()调用!)

为使C++满足我们的想法,我们必须放弃成员选取运算符而转用解引用运算符,就像以下代码示例中一样:

C cont = . . .
I it = cont.begin();
(*it)->release();

这是迭代器语法中恼人的小缺点。

在迭代器中支持指针成员选取运算符,没什么实质的意义,而仅仅是语法糖。我认为标准中将这规定为迭代器概念的一个特性是严重的错误。在我的日常工作中,除了仅有几个特例外,我完全避免使用迭代器的指针成员选取运算符,而使用解引用和点号成员选取运算符。我建议你也这么做。

Tip: Prefer iterator dereference and the dot member selection operator ((*it).m) over the pointer member selection operator (it->m).

提示: 使用解引用及点号成员选择运算符((*it).m)代替指针成员选择运算符(it->m)。

(转载请注明来源于金庆的专栏)
分享到:
评论

相关推荐

    wpktool unpacker (Sun online)

    example on how it works. wpktool ver.0.2 Usage : wpktool -d &lt;wpk_file&gt; [dest_dir] wpktool -l &lt;wpk_file&gt; wpktool -m &lt;wpk_file&gt; &lt;merge_file&gt; [address] wpktool -m &lt;wpk_file&gt...

    MongoDB_学习笔记

    - **it**:保存上一条命令的结果,通常用于进一步迭代查询结果。 **1.5 退出** - **exit** 或 **quit**:退出 MongoDB shell。 --- #### 二、PHP 语言下的 MongoDB 操作 **2.1 创建连接** - **$connection = ...

    java_msn.rar_The P.I_listener_mp3 plugin

    If I m listening Marilyn Manson - This Is The New Shit , Prefix : Jang-Ho Hwang listen Postfix: ~* When winamp song was changed, your nickname will be Jang-Ho Hwang listen Marylyn Manson - This ...

    笔记本配置清单

    - **NVIDIA GeForce GT 630M**: 这是一款面向中端市场的移动显卡,适用于笔记本电脑。它支持DirectX 11,并且具有一定的图形处理能力,可以满足大部分主流游戏的需求。 - **1GB DDR3**: 显存容量为1GB,采用DDR3标准...

    CPU-Z 1.47,CPU 查看工具

    - VIA P4M890 and P4M900 chipsets. - NVIDIA 650i and 680i chipset. - AMD Athlon 64 FX-7x processor. - Core 2 Duo E6850, E6750, E6650 processors. - socket 775 Xeon processor. - New parameters "-txt" and...

    cpuz 1.0 完美版

    Value is expressed in hexadecimal, and consists in a classic Red/Green/Blue color code : RRGGBB 信息框使用字体颜色。RBG颜色:RRGGBB/000060 - LabelFontName : Font used for the label boxes. 标签框字体...

    experimental-transform-seed

    # rm -rf .git && git init && git commit -m "Make it so" # optionally reset git history npm i # install dependencies ###Development 使用npm run dev运行开发服务器 现在开发服务器应该在 localhost:1618 上...

    space:著名的渲染引擎测试应用

    # rm -rf .git && git init && git commit -m "Make it so" # optionally reset git history npm i # install dependencies ###Development 使用npm run start dev运行开发服务器 现在开发服务器应该在 localhost:...

    FamousPlanets:实验性 WebGL 著名渲染

    #Engine-Seed 启动著名引擎的种子项目 ###安装git clone https://github.com/Famous/engine-seedcd engine-seed# rm -rf .git && git init && git commit -m "Make it so" # optionally reset git historynpm i #...

    new_famous_dna

    # rm -rf .git && git init && git commit -m "Make it so" # optionally reset git history npm i # install dependencies ###Development 使用npm run start-dev运行开发服务器 现在开发服务器应该在 localhost:...

    famousSpeedTest

    # rm -rf .git && git init && git commit -m "Make it so" # optionally reset git history npm i # install dependencies ###Development 使用npm run dev运行开发服务器 现在开发服务器应该在 localhost:1618 上...

    数据库集群系统设备清单 机型 技术参数 数量 数据库集群服务器 4U机 ....docx

    - **CPU**: 2 * INTEL 至强四核 E5620 (2.4GHz / 12M / 互联总线带宽 5.86GT/s,支持超线程) - **内存**: 4 * 2GB ECC Unbuffered DDR3-1066 内存 - **硬盘**: 2 * 300G 3.5寸 SAS 热插拔硬盘 - **RAID**: 256MB ...

    未来人类s5 BIOS 16l1 E16L1IT8.30E

    描述中提到的 "未来人类s5 bios E16L1IT8.30E 改GT62VR 7RD" 暗示这次BIOS更新可能特别针对了将未来人类s5笔记本的显卡从原厂配置升级到GT62VR 7RD的情况。GT62VR 7RD是一款基于NVIDIA GeForce GTX 1060显卡的游戏...

    model-class-methods-reading-online-web-sp-000

    模型类方法 目标 知道何时使用模型类方法 创建用于自定义查询的模型类方法 ...&lt; h1&gt; Believe It Or Not I'm Blogging On Air &lt;!-- add this new code above the @posts.each loop --&gt; &lt; h3&gt; F

    dsdt(gt630M)

    【标题】"dsdt(gt630M)"指的是在IT领域中与显卡GT630M相关的DSDT(Differentiated System Description Table)工作。DSDT是ACPI(Advanced Configuration and Power Interface)规范的一部分,它定义了硬件平台如何...

    模型类方法阅读v-000

    模型类方法 目标 知道何时使用模型类方法 创建用于自定义查询的模型类方法 ...&lt; h1&gt; Believe It Or Not I'm Blogging On Air &lt;!-- add this new code above the @posts.each loop --&gt; &lt; h3

    华硕N550JV GT750M 驱动安装

    6. **使用驱动安装包**:根据提供的文件名列表,\8073589_N550JV GT750M 驱动安装.rar很可能是华硕官方或第三方提供的驱动安装包。下载并解压此RAR文件,运行里面的安装程序,按照提示步骤完成驱动安装。 7. **检查...

    《微机系统与保护实训报告》.pdf

    - **硬盘**:日立320GB SATAII 16M,用于长期存储数据。 - **显卡**:9600GT加强版,用于图形处理。 - **显示器**:如AOC 2091V,显示输出设备。 - **其他组件**:还包括网卡、声卡、电源、光驱等,它们共同构成...

    r40_tinav2.1_最终验证通过_使用CB-S来验证OV5640有横条纹fpscamera+SPI2.0成功_20171114_1443没有外层目录.7z

    r40_tinav2.1_最终验证通过_使用CB-S来验证OV5640有横条纹fpscamera+SPI2.0成功_20171114_1443没有外层目录.7z 开发板:CB-S 1、(可选修改/调试技巧:) 除了ov5640.c之外,其它的驱动都不编译,节省编译时间!...

Global site tag (gtag.js) - Google Analytics