运算符->的重载比较特别,它只能是非静态的成员函数形式,而且没有参数。

1、如果返回值是一个原始指针,那么就将运算符的右操作数当作这个原始指针所指向类型的成员进行访问;

2、如果返回值是另一个类型的实例,那么就继续调用这个返回类型的operator->(),直到有一个调用返回一个原始指针为止,然后按第一种情况处理。

如果上述条件不满足(如:右操作数不是返回的原始指针指向的类型中的成员,或者,返回的非指针类型(另一个类型的实例)没有重载operator->()),那么编译将报错。

以下是用于验证的程序片段:

/*******************************************************
* File Name:main.cpp
* Description:演示成员访问操作符->的重载 
* Version:V1.0 
* Author:Mengjia 
* Date:2018-05-20 
* Copyright (C)2018, Mengjia
* Others:
******************************************************************************
运算符->的重载比较特别,它只能是非静态的成员函数形式(即不能在类外重载),
而且没有参数。
1、如果返回值是一个原始指针,那么就将运算符的右操作数当作这个原始
指针所指向类型的成员进行访问;
2、如果返回值是另一个类型的实例,那么就继续调用这个返回类型的operator->(),直到
有一个调用返回一个原始指针为止,然后就按第一种情况处理。 如果上述条件不满足(如:右操作数不是返回的原始指针指向的类型的成员,或者,
返回的另一个类型的实例中没有重载operator->()),那么编译将报错。
******************************************************************************
*******************************************************/
#include <iostream>
using namespace std; //原始类
struct Origin
{
int a;
};
//包装器类1,包装Origin类
struct Wrapper
{
Origin* orig;
Origin* operator->() const
{
return orig; //返回原始指针
}
};
//包装器类2,包装Wrapper类
struct Wrapper2
{
Wrapper* wrap;
Wrapper& operator->() const
{
return *wrap; //返回类对象
}
};
int main()
{
Origin o;
o.a = ;
Wrapper w;
w.orig = &o;
Wrapper2 w2;
w2.wrap = &w; cout << "w->a" << "\t\t\t\t" << w->a << endl;
cout << "w.operator->()" << "\t\t\t" << w.operator->() << endl;
cout << "w.operator->()->a" << "\t\t" << w.operator->()->a << endl; cout << "w2->a" << "\t\t\t\t" << w2->a << endl;
cout << "&w2.operator->()" << "\t\t" << &w2.operator->() << endl;
cout << "w2.operator->()->a" << "\t\t" << w2.operator->()->a << endl;
cout << "w2.operator->().operator->()" << "\t" << w2.operator->().operator->() << endl;
cout << "w2.operator->().operator->()->a" << "\t" << w2.operator->().operator->()->a << endl; system("pause");
return ; } /*
*输出结果:
w->a 7
w.operator->() 00AFF7E4
w.operator->()->a 7
w2->a 7
&w2.operator->() 00AFF7D8
w2.operator->()->a 7
w2.operator->().operator->() 00AFF7E4
w2.operator->().operator->()->a 7
**/

其中,最为诡异的就是w2->a输出的是7。

按照上面总结的结论,这个调用其实会被编译器转换成w2.operator->().operator->()->a的形式,所以输出的是7。

转自《C++对成员访问操作符->的重载》

【转】C++对成员访问运算符->的重载的更多相关文章

  1. C++题目一道: 重载`->': 您真的懂成员访问运算符的重载吗?

    原题目在这里: http://hi.baidu.com/shilyx/item/672736e14a14a90c64db003a 要求: //给出类Test的定义和实现,使程序编译通过, //并且ma ...

  2. C++派生类成员访问作用域,同名重载

    #include <iostream> using namespace std; class CFatherSum //父类Sum { public: int m_iVar; //公用数据 ...

  3. c/c++ 重载运算符 关系,下标,递增减,成员访问的重载

    重载运算符 关系,下标,递增减,成员访问的重载 为了演示关系,下标,递增减,成员访问的重载,创建了下面2个类. 1,类StrBlob重载了关系,下标运算符 2,类StrBlobPtr重载了递增,抵减, ...

  4. C# 主要运算符中的成员访问(?.)

    在开发过程中,我遇到了一种null 条件成员访问的写法,开始不太理解,之后专门查了微软的官方文档,下面是具体内容:   三种成员访问的三种形式 (1)x.y:成员访问. (2)x?.y:null 条件 ...

  5. C++ 重载运算符和重载函数

    C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...

  6. C++解析七-重载运算符和重载函数

    重载运算符和重载函数C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载.重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列 ...

  7. 吴裕雄--天生自然C++语言学习笔记:C++ 重载运算符和重载函数

    C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不 ...

  8. C++基础 (4) 第四天 this指针 全局函数和成员函数 友元 操作符重载

    1static强化练习-仓库进货和出货 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; c ...

  9. C++ 流插入"<<"和流提取">>"运算符的重载

    01 流插入<<运算符的重载 C++ 在输出内容时,最常用的方式: std::cout << 1 <<"hello"; 问题: 那这条语句为什么 ...

随机推荐

  1. Hadoop问题:There are 0 datanode(s) running and no node(s) are excluded in this operation.

    问题描述: org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /tmp/hadoop-yarn/staging/hado ...

  2. Hadoop记录-Ganglia监控HDFS和HBase指标说明

    HDFS相关 datanode相关 参数 解释 dfs.datanode.blockChecksumOp_avg_time 块校验平均时间 dfs.datanode.blockChecksumOp_n ...

  3. ruby读取exce文件,使用roo---Gem

    module SEquipsHelper #设备台账,从excel文件读取信息 require 'roo' #require 'roo-xls' #读取excel文件 # SEquipsHelper. ...

  4. KMP算法的next[]数组 的求法

    例如: next数组的求解方法是:第一位的next值为0,第二位的next值为1,后面求解每一位的next值时,根据前一位进行比较.首先将前一位与其next值对应的内容进行比较,如果相等,则该位的ne ...

  5. 【转】C语言中的符号优先级

    转自: http://blog.csdn.net/huangblog/article/details/8271791 虽然在日常使用中,添加括号来明确规定运算符优先级是一种常识,但毕竟学校考试就喜欢考 ...

  6. ubuntu 配置minicom 进行串口开发

    sudo apt-get install minicom        sudo minicom -s        Serial port setup        Save  setup as d ...

  7. Linux下Maven私服Nexus3.x环境构建操作记录【转】

    Maven介绍Apache Maven是一个创新的软件项目管理和综合工具.Maven提供了一个基于项目对象模型(POM)文件的新概念来管理项目的构建,可以从一个中心资料片管理项目构建,报告和文件.Ma ...

  8. 前端基础之JQuery - day15

    写在前面 上课第15天,打卡: 张国臂掖,以通西域: ########### # 课上简书 # ########## http://jquery.cuishifeng.cn/index.html JQ ...

  9. 十三、u-boot 调试-- NOR FLASH 支持

    13.1 问题现象 在烧写进去的u-boot 中 Flash 并没有显示实际大小,需要进行修改. 13.2 问题定位过程 13.2.1 关键字搜索 Flash: 此关键字在 Board_r.c (co ...

  10. bzoj 1531 Bank notes 多重背包/单调队列

    多重背包二进制优化终于写了一次,注意j的边界条件啊,疯狂RE(还是自己太菜了啊啊)最辣的辣鸡 #include<bits/stdc++.h> using namespace std; in ...