C++ - (*) 之间的区别。和->?

Posted

技术标签:

【中文标题】C++ - (*) 之间的区别。和->?【英文标题】:C++ - Difference between (*). and ->? 【发布时间】:2011-01-29 00:58:28 【问题描述】:

在性能或其他方面是否存在差异:

ptr->a();

(*ptr).a(); 

?

【问题讨论】:

【参考方案1】:

-> 运算符的特殊之处在于,在大多数情况下,它会递归地“向下钻取”,直到表达式的结果不再是为其定义了重载 -> 运算符的东西。 (*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**,所以它不符合条件。

【讨论】:

@Jeremy:我添加了一些反引号,以防止星号被解释为格式化命令:)。【参考方案2】:

[编辑]

如果变量定义为 T*(其中 T 是某种类型),那么 -> 和 * 都是相同的(除非 ptr 为空)。

如果变量是类的实例(按值或按引用),那么 -> 和 * 的行为应该相同(根据最佳实践),但这需要类以相同的方式重载它们。

【讨论】:

-> 和 * 不是对类型 T 本身进行操作,而是对一个 T* 类型进行操作,它是一个指针。 如果基础类确实 重载-&gt;* 它应该重载两者以使其仍然相同。否则它的设计很糟糕。 @Tadeusz Kopec:阅读 Jeremy Bell 的回答:operator-&gt; 具有特殊行为,在某些情况下使x-&gt;y(*x).y 不一致,并且无法用operator* 模拟该行为 Rachel:我知道人们一遍又一遍地听到这个,但是:为什么?谁在乎?使用可读的,性能是第二个问题。您首先关心的是以一种易于管理的方式编写您的应用程序。只有当你发现性能不足时,你才应该关心性能。也就是说,您必须profile:对代码计时,看看哪个更快。但是在这种情况下,它们是相同的。应该没有区别。我猜你是 C++ 编程的新手,所以担心 C++,而不是速度。 @Tadeusz:您可以重载-> 但它将适用于类而不是类的指针。例如猫 c; c->f(),它不适用于 Cat *p = &c; p->f();我不知道为什么它的投票率如此之高,因为它是错误的。【参考方案3】:

因为您在 cmets 中要求它。您可能正在寻找的内容可以在标准中找到(5.2.5 类成员访问):

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

编译器将产生完全相同的指令,并且同样高效。你的机器不会知道你写的是“->”还是“*.”。

【讨论】:

是的。这就是我一直在寻找的东西——无论它们下面是否相同。

以上是关于C++ - (*) 之间的区别。和->?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中包含头文件时尖括号 < > 和双引号“”之间的区别? [复制]

对象和实例之间的区别:C++

void 指针:C 和 C++ 之间的区别

c++ 中空类的大小和联合、结构和类之间的区别是啥?

C 和 C++ 之间的条件运算符区别

这个 C++ 函数和 Python 函数之间的区别