【发布时间】:2011-01-29 00:58:28
【问题描述】:
在性能或其他方面是否存在差异:
ptr->a();
和
(*ptr).a();
?
【问题讨论】:
标签: c++ pointers dereference
在性能或其他方面是否存在差异:
ptr->a();
和
(*ptr).a();
?
【问题讨论】:
标签: c++ pointers dereference
-> 运算符的特殊之处在于,在大多数情况下,它会递归地“向下钻取”,直到表达式的结果不再是为其定义了重载 -> 运算符的东西。 (*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**,所以它不符合条件。
【讨论】:
[编辑]
如果变量定义为 T*(其中 T 是某种类型),那么 -> 和 * 都是相同的(除非 ptr 为空)。
如果变量是类的实例(按值或按引用),那么 -> 和 * 的行为应该相同(根据最佳实践),但这需要类以相同的方式重载它们。
【讨论】:
-> 或* 它应该重载两者以使其仍然相同。否则它的设计很糟糕。
operator-> 具有特殊行为,在某些情况下使x->y 与(*x).y 不一致,并且无法用operator* 模拟该行为
因为您在 cmets 中要求它。您可能正在寻找的内容可以在标准中找到(5.2.5 类成员访问):
3 如果 E1 具有“指向类的指针”类型 X,” 那么表达式 E1->E2 是 转换为等价形式 (*(E1)).E2;
编译器将产生完全相同的指令,并且同样高效。你的机器不会知道你写的是“->”还是“*.”。
【讨论】: