C++ - (*).和->的区别是什么?

13

在性能或其他方面,以下两者是否有任何区别:

ptr->a();

(*ptr).a(); 

?

3个回答

15
如果变量定义为T*(其中T是某种类型),则->和*相同(除非ptr为null)。
如果变量是类的实例(按值或按引用),则->和*应该表现相同(按最佳实践),但这需要类以相同的方式重载它们。

1
&和不作用于类型本身T,而是作用于T类型的指针。 - Brian R. Bondy
8
如果底层类确实重载了->*,那么它应该同时重载两者,以便仍然保持相同。否则,它的设计不好。 - Tadeusz Kopec for Ukraine
2
@Tadeusz Kopec:请阅读Jeremy Bell的答案:“operator->”具有特殊行为,使得在某些情况下“x->y”与“(x).y”不一致,并且该行为无法使用“operator”模拟。 - David Rodríguez - dribeas
2
Rachel: 我知道人们已经听到这个问题很多次了,但是:为什么?谁在乎?使用可读性更好的代码,性能是次要的关注点。你首要的关注是以易于管理的方式编写应用程序。只有当你发现性能不足时,才应该关心性能问题。也就是说,你必须进行剖析:计时代码并查看哪一个更快。但在这种情况下,它们是相同的。不应该有任何区别。我猜你在C++编程方面还比较新,所以先关注C++本身,而不是速度。 - GManNickG
3
@Tadeusz:你可以进行重载 -> 但它将适用于类,而不是类的指针。例如Cat c; c->f(),它不适用于Cat *p =&c; p->f(); 我不确定为什么此回答被投票高居首位,因为它是错误的。 - Brian R. Bondy
显示剩余10条评论

12

既然您在评论中提到了这个问题,那么您可能正在寻找的内容可以在标准文档(5.2.5类成员访问)中找到:

3 如果 E1 的类型是“指向类 X 的指针”,那么表达式 E1->E2 将被转换为等效形式 (*(E1)).E2;

编译器将生成完全相同的指令,并且效率也不会受到影响。您的计算机不知道您是使用“->”还是“*.”来进行操作。


是的,这就是我想要的 - 它们是否在底层相同。 - Rachel

8
-> 运算符在大多数情况下是特殊的,因为它会递归地“向下钻取”,直到表达式的结果不再是为其定义了重载 -> 运算符的内容。而 (*subxpression).x 表达式只对子表达式进行一次解引用,因此如果 (*subexpression) 的结果是另一个指针,则无法编译(您需要编写 (*(*subexpression)).x)。请参见以下代码以获得更好的说明:
#include <iostream>
using namespace std;

class MyClass
{
public:
    MyClass() : x(0) {}
    int x;
};

class MyPtr
{
private:
    MyClass* mObj;
public:
    MyPtr(MyClass* obj) : mObj(obj) {}
    MyClass* operator->() 
    {
        return mObj;
    }
};

int main() 
{
    MyClass obj;
    MyClass* objCPtr = &obj;
    MyClass** objCHandle = &objCPtr;
    MyPtr ptr(&obj);
    cout << ptr->x << endl;
    cout << (*(*objCHandle)).x << endl;
}

然而需要注意的是,以下代码将无法通过编译:

cout << objCHandle->x << endl;

->的下钻行为仅在表达式的左侧为类、结构体、联合体或通用类型时发生。在此情况下,objCHandle是一个MyClass**,因此不符合条件。


1
@Jeremy:我添加了一些反引号,以防止星号被解释为格式化命令 :)。 - Andrew Aylett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接