如何arrow->运算符重载在c ++内部工作?

时间:2012-05-20 22:36:57

标签: c++ operator-overloading

我理解正常的运算符重载。编译器可以直接将它们转换为方法调用。我不是很清楚 - >运营商。我正在编写我的第一个自定义迭代器,我觉得需要 - >运营商。我看了一下stl源代码并实现了我自己的代码:

MyClass* MyClassIterator::operator->() const
{
    //m_iterator is a map<int, MyClass>::iterator in my code.
    return &(m_iterator->second);
}

然后我可以使用MyClassIterator的实例,如:

myClassIterator->APublicMethodInMyClass().

看起来编译器在这里执行了两个步骤。 1.调用 - &gt;()方法获取临时的MyClass *变量。 2.在temp变量上调用APublicMethodInMyClass使用它的 - &gt;操作

我的理解是否正确?

2 个答案:

答案 0 :(得分:75)

operator->在语言中具有特殊语义,当重载时,它会将自身重新应用于结果。虽然其余的运算符只应用一次,但编译器将根据需要多次operator->应用原始指针,再次访问该指针所引用的内存。

struct A { void foo(); };
struct B { A* operator->(); };
struct C { B operator->(); };
struct D { C operator->(); };
int main() {
   D d;
   d->foo();
}

在前面的示例中,在表达式d->foo()中,编译器将获取对象d并将operator->应用于它,从而生成类型为C的对象,它然后将重新应用运算符以获取B的实例,重新应用并转到A*,之后它将取消引用该对象并获取指向的数据。

d->foo();
// expands to:
// (*d.operator->().operator->().operator->()).foo();
//   D            C            B           A*

答案 1 :(得分:27)

myClassIterator->APublicMethodInMyClass()

只是以下内容:

myClassIterator.operator->()->APublicMethodInMyClass()

对重载operator->的第一次调用会获得某种类型的指针,该指针具有一个名为APublicMethodInMyClass()的可访问(来自您的调用站点)成员函数。当然,遵循通常的功能查找规则来解析APublicMethodInMyClass(),具体取决于它是否是虚拟的。

不一定是临时变量;编译器可能会也可能不会复制由&(m_iterator->second)返回的指针。很可能,这将被优化掉。不会创建MyClass类型的临时对象。

通常的警告也适用于m_iterator - 确保您的调用不会访问无效的迭代器(例如,如果您使用的是vector)。