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* 类型进行操作,它是一个指针。 如果基础类确实 重载->
或*
它应该重载两者以使其仍然相同。否则它的设计很糟糕。
@Tadeusz Kopec:阅读 Jeremy Bell 的回答:operator->
具有特殊行为,在某些情况下使x->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++ - (*) 之间的区别。和->?的主要内容,如果未能解决你的问题,请参考以下文章