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

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. JAVA核心技术I---JAVA基础知识(文本文件读写)

    一:java IO包概述 (一)Java读写文件,只能以(数据)流的形式进行读写 (二)java IO 包 –节点类:直接对文件进行读写 –包装类 • 转化类:字节/字符/数据类型的转化类 • 装饰类 ...

  2. com.netflix.client.ClientException: Load balancer does not have available server for client xxxx

    版本 spring boot: 2.0.1.RELEASE spring cloud: Finchley.M9 错误 通过zuul调用eureka注册的服务,错误内容如下 Caused by: com ...

  3. windows10下TensorFlow安装记录

    1.安装anaconda 安装最新版:https://repo.anaconda.com/archive/Anaconda3-5.3.0-Windows-x86_64.exe 加入环境变量: path ...

  4. Http状态码解释

    参考:urllib与urllib2的学习总结(python2.7.X) # Table mapping response codes to messages; entries have the # f ...

  5. 验证调用HttpServletResponse.getWriter().close()方法是否真的会关闭http连接

    起因 线上项目突然遭到大量的非法参数攻击,由于历史问题,之前的代码从未对请求参数进行校验. 导致大量请求落到了数据访问层,给应用服务器和数据库都带来了很大压力. 针对这个问题,只能对请求真正到Cont ...

  6. JDK8新特性04 方法引用与构造器引用

    import java.io.PrintStream; import java.util.Comparator; import java.util.function.*; /** * 一.方法引用 * ...

  7. ASP.NET Web API 2 之 HttpRequestMessage 对象

    Ø  前言 在 Web API 中经常会使用到 HttpRequestMessage 和 HttpResponseMessage 对象,这两个对象封装了对 Web API 的请求和响应,位于 Syst ...

  8. nginx + iis 使用介绍

    1.下载 nginx 2.配置nginx 文件 1)配置该目录下E:\nginx\nginx-1.9.3\conf: #user nobody; worker_processes ; #error_l ...

  9. mssql 创建存储过程简单实例

    CREATE procedure [dbo].[cp_User_Increment] @channelId int, @currentPage int, @pageSize int, @userId ...

  10. oracle 导入execl

    如果没有配置好的,就需要添加一个 如果找不到相应的驱动就安装AccessDatabaseEngine.exe