C++ Primer, Fifth Edition:这个类的最后一行,为何返回的是地址?我一直觉得应该是return this->operator*();
才对啊。不是说p->mem
和(*p).mem
应该是一样的吗?
class StrBlobPtr
{
public:
std::string& operator*() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr]; // (*p) is the vector to which this object points
}
std::string* operator->() const
{
// delegate the real work to the dereference operator
return & this->operator*();
} // other members as before
};
The dereference operator checks that curr is still in range and, if so, returns a reference to the element denoted by curr. The arrow operator avoids doing any work of its own by calling the dereference operator and returning the address of the element
returned by that operator.
请看代码:定义了3个类,C包含B,B包含A。A、B、C都定义了一个action的成员函数。B和C都重载箭头操作符,不同的是B的重载箭头操作符返回的是A类对象的指针,而C的重载箭头操作符返回的是B类对象(也就是你的疑问所在地)。
程序的输出:
Action in class C!
Action in class A!
1
第一个输出比较好理解,就不解释了。对于第二个输出和第三个输出比较奇怪,为什么会是这样我们看看官方的约定描述:
这就解释了上面的操作c->action();的输出,因为 c-> 返回的是B类型而不是指针,所有程序会迭代操作B类型的->重载函数,此时返回的是A类型指针,那么此时不再迭代下去找到A的action()函数。如果A没有action()函数,就会出错。所以 c->action();这句代码的实际运行是这样的:c.operator->().operator->()->action();第三个输出也是同理c->x;实际运行是c.operator->().operator->()->x ,所有即使 C 的 x 变量是private 也不会影响程序,甚至警告都不会有。
在你的程序中如果返回的不是指针,那么程序会迭代查找 std::string的->操作 该操作返回的就是你执行 StrBlobPtr-> 操作的返回值,你觉得这是不是你希望的呢?也就是说如果返回的是类型而不是指针-> 会无限迭代下去直到返回的是指针然后再调用你开始指定的方法或者成员变量,这就是->所特有的不同的地方。