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

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

ptr->a();

(*ptr).a(); 

?

【问题讨论】:

    标签: c++ pointers dereference


    【解决方案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;

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

    【讨论】:

    • 是的。这就是我一直在寻找的东西——无论它们下面是否相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 2010-10-23
    • 2013-05-02
    • 1970-01-01
    • 2014-02-03
    • 2012-01-21
    • 2013-07-22
    相关资源
    最近更新 更多