为什么运营商 - >手动超载?

时间:2010-05-30 12:11:11

标签: c++ pointers operator-overloading smart-pointers

如果p->m只是(*p).m的语法糖,那会不会有意义?基本上,我写过的每个operator->都可以实现如下:

Foo::Foo* operator->()
{
    return &**this;
}

在任何情况下我都希望p->m表示除(*p).m之外的其他内容吗?

5 个答案:

答案 0 :(得分:18)

operator->()具有隐式调用重复的奇怪区别,而返回类型允许。最明显的方法是使用代码:

struct X {
    int foo;
};

struct Y {
    X x;
    X* operator->() { return &x; }
};

struct Z {
    Y y;
    Y& operator->() { return y; }
};

Z z;
z->foo = 42;          // Works!  Calls both!

我记得有一种情况,当需要这种行为来使一个对象在类似智能指针的上下文中作为另一个对象的代理时,尽管我不记得细节。我记得的是,我只能通过使用a->b语法,通过使用这个奇怪的特殊情况,让我的行为按照我的预期工作;我找不到让(*a).b同样工作的方法。

不确定这会回答你的问题;我真的在说,“好问题,但它甚至比那更奇怪!”

答案 1 :(得分:3)

一个用例可能是你在C ++中创建一个DSL,沿着Boost Karma的行(尽管它们的库中似乎没有重载->),你完全改变了传统C ++运算符的含义。这是一个好主意肯定是辩论。

答案 2 :(得分:1)

常规指针提供p->m(*p).m,其中p->m是最常见的。如果您只允许重载其中一个,那么它将与默认类型不一致。至于为什么不让编译器重写它,简单的答案是因为有时候,你不需要operator->返回T *,其中operator *返回T&。允许它们单独过载允许您不一定能想到的组合。但是,仅仅因为我们目前无法想出改变它的任何理由而拒绝它将是愚蠢的。很像,你可以有一个int128类和重载运算符+ =来代表取幂,如果你想要的话。

答案 3 :(得分:0)

你可能想做一些其他的操作,比如递增变量(访问计数)甚至是一些安全检查等。另一方面,我从来不需要重载操作符 - > ...

答案 4 :(得分:-1)

我认为它用于shared_ptr<>在加强(例如)。这使得它们看起来像普通指针一样,虽然它们是特殊指针(引用计数afaik)。