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

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. Spring Boot 启动:No active profile set, falling back to default profiles: default

    启动 Spring Boot 失败,但是没有出现多余的异常信息: 检查之后发现是依赖的问题(之前依赖的是 spring-boot-starter),修改即可: 方法二: pom.xml加上下面两个依赖 ...

  2. 解决 git push Failed to connect to 127.0.0.1 port 8-87: 拒绝连接

    今天在本地使用nsq 测试的时候总是提示端口被占用 通过查看环境变量确实存在该代理 如何解决 使用netstat 命令查看端口被占用情况 根据经常ID号查看是哪一个进程正在被占用 如何还是不行,则在[ ...

  3. ArcGis Python脚本——根据字段内容拆分要素类(shp)为多个

    其实,这就是批量执行了ArcToolbox 分析工具-筛选 功能. 先上代码,后做解说: # in_feature:待拆分要素类 # out_folderpath:输出路径,注意最后加“/”以与字段名 ...

  4. 32. Springboot 系列(八)动态Banner与图片转字符图案的手动实现

    使用过 Springboot 的对上面这个图案肯定不会陌生,Springboot 启动的同时会打印上面的图案,并带有版本号.查看官方文档可以找到关于 banner 的描述 The banner tha ...

  5. mysql字符函数

    1.CONCAT()  字符连接 (1)mysql> SELECT CONCAT('imooc', 'MYSQL');+--------------------------+| CONCAT(' ...

  6. intptr_t 指针

    对于64为系统: typedef  signed char  int8_t; typedef short int int16_t; typedef int int32_t; # if __WORDSI ...

  7. ubuntu安装matplotlib一些坑

    ubuntu16.04,python2.7 安装matplotlib, 1.在root权限下执行命令 pip install matplotlib==1.5.1 这里有个困扰我一个星期的问题,系统都被 ...

  8. node里面的buffer理解

    node提供了专门读写文件的模块,文件内容都是2进制存放在内存中的 node读取文件的结果都是16进制,那么你要学会进制转换,二进制0b开头 ,八进制0开头,十六进制0x 基础知识: 1字节=8bit ...

  9. python判断小数示例&写入文件内容示例

    #需求分析: #1.判断小数点个数是否为1 #2.按照小数点分隔,取到小数点左边和右边的值 #3.判断正小数,小数点左边为整数,小数点右边为整数 #4.判断负小数,小数点左边以负号开头,并且只有一个负 ...

  10. Linux环境及基础命令(一)

    Linux环境及基础命令 一.认识Linux系统 略 二.配置Linux系统远程登录 2.1虚拟机系统配置 2.11虚拟机配置 统一NAT模式 虚拟机连不上 确定VMnet8网卡的IP地址(每台虚拟机 ...