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

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. C++回顾day01---<C++对C的增强>

    一:命名空间 二:三目运算符 (一)C语言三目运算符返回值(不可修改) (二)C++中三目运算符直接返回变量本身(可以直接进行修改) 三:C++要求所有函数必须有类型(不重要) (一)C语言允许函数无 ...

  2. JAVA核心技术I---JAVA基础知识(异常处理类)

    一:异常分类 Throwable:所有错误的祖先. Error:系统内部错误或者资源耗尽.不用我们管 Exception: 程序有关的异常.重点关注 –RuntimeException: 程序自身的错 ...

  3. Kafka权威指南 读书笔记之(四)Kafka 消费者一一从 Kafka读取数据

    KafkaConsumer概念 消费者和消费者群组 Kafka 消费者从属于消费者群组.一个群组里的消费者订阅的是同一个主题,每个消费者接收主题一部分分区的消息. 往群组里增加消费者是横向伸缩消费能力 ...

  4. Linux记录-使用python临时搭建web服务器

    python2: python -m SimpleHTTPServer 8888 python3: python -m http.server 8888 wget   ip:8888/文件

  5. 项目thymeleaf

    官方文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#link-urls 定义和引用片段 在我们的模板中,我们经常需 ...

  6. CodeForces - 867E Buy Low Sell High (贪心 +小顶堆)

    https://vjudge.net/problem/CodeForces-867E 题意 一个物品在n天内有n种价格,每天仅能进行买入或卖出或不作为一种操作,可以同时拥有多种物品,问交易后的最大利益 ...

  7. 微信小程序入门教程(一)API接口数据记录

    今天测试用小程序调用API接口,发现有些数据打印都是对象,怎么全部打印详细点来 小程序代码: httpsearch: function (name, offset, type, cb) { wx.re ...

  8. Ant和Maven

    Ant和Maven都是基于Java的构建(build)工具.理论上来说,有些类似于(Unix)C中的make ,但没有make的缺陷.Ant是软件构建工具,Maven的定位是软件项目管理和理解工具. ...

  9. ubuntu常用

    一.查看分区磁盘的速度命令 $ hdparm -Tt /dev/sda1 在终端打印出如下信息: /dev/sda1: Timing cached reads: MB in 2.00 seconds ...

  10. ZooKeeper基础

    ======================================ZooKeeper 背景======================================ZooKeeper 是一 ...