C++
中箭头运算符重载的基本用法就不讲了,这里主要关注箭头运算符重载后,在使用时需要注意的细节问题。其中最重要的一个问题就是,如果我们在重载箭头运算符时返回了一个重载了箭头运算的对象,那么这个箭头指向运算将会一直进行下去,直到程序返回了所需的内容,或者是返回错误。
假设,point
是一个指向类对象的指针或者是一个重载了 operator->
的类的对象,则 point->mem
的执行过程如下所示:
- 如果
point
是指针,则应用内置的箭头运算符,表达式等价于(*point).mem
。也就是,首先解引用该指针,然后从所得的对象中获取指定的成员。如果point
所指的类型没有名为mem
的成员,则程序会发生错误。 - 如果
point
是定义了operator->
的类的一个对象,则使用point.operator->()
的结果来获取mem
。若该结果是一个指针,则执行上述第1
步的流程;若该结果本身含有重载的operator->()
,则重复调用当前步骤。最终,当这一过程结束时程序或者返回了所需的内容,或者返回一些表示程序错误的信息。
为此,下面这个例子可以说明上述过程:
#include <iostream>
class D
{
public:
void show(void) const { std::cout << "show D" << std::endl; }
};
class C
{
public:
C() { obj = new D; }
void show(void) { std::cout << "show C" << std::endl; }
const D* operator->() const {
return obj;
}
private:
D* obj;
};
class B
{
public:
void show(void) { std::cout << "show B" << std::endl; }
const C& operator->() const {
return obj;
}
private:
C obj;
};
class A
{
public:
void show(void) { std::cout << "show A" << std::endl; }
const B& operator->() const {
return obj;
}
private:
B obj;
};
int main(void)
{
A a;
a->show();
return 0;
}
程序运行结果如下所示:
$ g++ -o main main.cpp
$ ./main
show D
参考资料:
- C++ primer(第五版)中文版。