当作为类的成员函数重载时,解引用运算符(*)如何工作?

时间:2016-11-02 01:09:50

标签: c++ operator-overloading smart-pointers dereference template-function

当我在operator overloading上查阅书籍和堆栈溢出文章时,我发现了以下内容:

  

当重载运算符是成员函数时,它绑定到   左手操作数。成员运算符函数少一个(显式)   参数比操作数的数量。

(Addison Wesley,C ++ Primer)

所以我的问题是,因为*(取消引用)运算符没有任何左操作数,它如何获取其参数(对象本身或this)?

3 个答案:

答案 0 :(得分:2)

对于所有前缀一元运算符,它对其后面的操作数进行操作。

  

作为一个补充问题,如果将overloaded *运算符定义为非成员函数与成员函数,则如何使用

在大多数情况下,不,除非非成员函数无法访问该类的私有成员,并且如果成员函数和非成员函数都存在,编译器需要使用overload resolution来选择更高级别的功能,如果没有更好的功能,那就是它的暧昧电话,请参阅ADL

对于可靠的来源,您可以查看标准C ++中的operator overloading,或更好的第13.5.1节[over.unary]:

  

前缀一元运算符应由非静态成员函数(9.3)实现,不带参数或   具有一个参数的非成员函数。因此,对于任何前缀一元运算符@,可以解释@x   作为x.operator @()或operator @(x)。如果已声明了两种形式的运算符函数,则   13.3.1.2中的规则确定使用哪种解释(如果有的话)。有关后缀的说明,请参见13.5.7   一元运算符++和 - 。   2同一运算符的一元和二元形式被认为具有相同的名称。 [注意:因此,   一元运算符可以隐藏二进制运算符与封闭范围,反之亦然。 -结束   注意]

如果同时存在成员和非成员,请参阅13.3.1.2 [over.match.oper]

答案 1 :(得分:0)

前缀*对其后面的操作数进行操作。

对于表示为成员函数的用户定义的operator*,这是this - 表达式引用的对象。

#include <iostream>
using namespace std;

struct S
{
    auto operator*() const -> char const* { return "Hi there!"; }
};

auto main()
    -> int
{ cout << *S() << endl; }

结果:

Hi there!

答案 2 :(得分:0)

取消引用运算符与重载运算符的工作方式与普通运算符完全相同。

int foo(int *p)
{
     return *p;
}

在语句return *p;中,解除引用运算符适用于指针p。它被传递到右侧:

作为一个重载运算符,它的工作方式相同。

class bar {

     int *some_internal_ptr;

public:
     int operator*() const {
          return *some_internal_ptr;
     }

     // Other class members and methods...
};

int foo(bar p)
{
     return *p;
}

*运算符的右侧是带有运算符*`成员的类时,它将作为类的重载方法被调用,与任何其他成员没有区别,以便解析该解除引用

这是因为使用相同是许多C ++库算法与指针或C ++库运算符同样良好的原因。例如,std::copy() 可以 实现如下(我正在修复一些与此无关的复杂性):

template<typename iter_type>
iter_type copy(iter_type b, iter_type e, iter_type t)
{
    while (b != e)
    {
       *t=*b;
       ++t;
       ++b;
    }
    return t;
}

您可以将本机指针传递给std::copy,或者使用重载的*运算符传递类似迭代器的类,并且因为使用了重载的*运算符,其语法与普通*相同{1}}运算符,同样的算法也适用于重载运算符。