重载成员访问运算符 - > ,.*(C++)

Bin*_*ngo 119 c++ operator-overloading c++-faq

据我所知大多数运算符重载,与成员访问运营商外->,.*,->*等.

特别是,传递给这些操作符函数的内容以及应返回的内容是什么?

操作员如何运作(例如operator->(...))知道所指的成员是什么?可以知道吗?它甚至需要知道吗?

最后,是否需要考虑常见因素?例如,当重载类似的东西时operator[],通常你需要const和非const版本.成员访问运算符是否需要const和非const版本?

Pot*_*ter 136

->

这是唯一真正棘手的问题.它必须是非静态成员函数,并且不带参数.返回值用于执行成员查找.

如果返回值是类类型的另一个对象,而不是指针,则后续成员查找也由operator->函数处理.这被称为"向下钻取行为".语言将operator->调用链接在一起,直到最后一个返回指针.

struct client
    { int a; };

struct proxy {
    client *target;
    client *operator->() const
        { return target; }
};

struct proxy2 {
    proxy *target;
    proxy &operator->() const
        { return * target; }
};

void f() {
    client x = { 3 };
    proxy y = { & x };
    proxy2 z = { & y };

    std::cout << x.a << y->a << z->a; // print "333"
}
Run Code Online (Sandbox Code Playgroud)

->*

这个只是棘手的,因为没有什么特别之处.的非过负荷版本需要指针的一个目的是类型在左手侧和指针的一个目的是在右侧构件类型.但是当你重载它时,你可以接受你喜欢的任何参数并返回你想要的任何东西.它甚至不必是非静态成员.

换句话说,这一次仅仅是一个正常的二进制运算一样+,-/.另请参阅:自由运算符 - >*是否超载邪恶?

.*.

这些不能超载.当左侧是类型时,已经存在内置意义.或许能够为左侧的指针定义它们会有一点意义,但语言设计委员会认为这将更加混乱而不是有用.

超载->,->*,.,并且.*只能在情况填写,其中一个表达式将是不确定的,它永远不会改变,这将是没有超载的有效表达的意思.

  • @Matt好吧,`new`总是被重载,或者重载规则并不真正适用于它(13.5/5:分配和释放函数,operator new,operator new [],operator delete和operator delete [],被描述完全在3.7.4.除非在3.7.4中明确说明,否则本子条款其余部分中的属性和限制不适用于它们.)但是重载一元`&`或二进制`&&`,`||`或` ,`,或者添加`operator =`的重载,或者为无范围的枚举类型重载任何东西,都可以改变表达式的含义.澄清声明,谢谢! (6认同)
  • 你最后的陈述并不完全正确.例如,您可以重载`new`运算符,即使它没有过载也有效. (2认同)

Tot*_*nga 31

操作员 - >很特别.

"它有额外的非典型约束:它必须返回一个对象(或对一个对象的引用),它也有一个指针解除引用操作符,或者它必须返回一个指针,该指针可用于选择指针取消引用操作符指向的内容. " Bruce Eckel:思考CPP Vol-one:operator->

为方便起见,提供了额外的功能,因此您无需致电

a->->func();
Run Code Online (Sandbox Code Playgroud)

你可以简单地做:

a->func();
Run Code Online (Sandbox Code Playgroud)

这使得operator - >与其他运算符重载不同.

  • 这个答案值得更多的信任,你可以从该链接下载Eckel的书,信息在第一卷的第12章. (2认同)

650*_*502 25

你不能超载成员访问.(即第二部分->).但是,您可以重载一元解除引用运算符*(即第一部分->).

C++ ->运算符基本上是两个步骤的结合,如果你认为它x->y相当于,那就很清楚了(*x).y.C++允许您在类的实例(*x)时自定义如何处理该部件x.

->重载的语义有点奇怪,因为C++允许您返回常规指针(它将用于查找指向的对象)或返回另一个类的实例(如果此类还提供->运算符).在第二种情况下,从这个新实例继续搜索解除引用的对象.

  • 很棒的解释!我想这对于` - >*`意味着相同,因为它相当于`(*x).*`的形式? (2认同)

Joh*_*ick 10

->运营商不知道正在指向什么成员,它只是提供了一个对象来执行实际的成员访问.

另外,我认为没有理由不能提供const和非const版本.


Asa*_*saf 6

当你重载operator - >()(这里没有传递参数)时,编译器实际上做的是递归调用 - >,直到它返回一个指向类型的实际指针.然后它使用正确的成员/方法.

例如,这对于创建封装实际指针的智能指针类很有用.调用重载的operator->,做它做的任何事情(例如锁定线程安全),返回内部指针,然后编译器调用 - >这个内部指针.

至于常数 - 它已在评论和其他答案中得到回答(你可以而且应该同时提供).