6

我对使用 C++ 很陌生。我以前处理过 Java 和 ActionScript,但现在我想学习这种强大的语言。由于 C++ 授予程序员显式使用指针的能力,我对箭头成员运算符的使用感到非常困惑。这是我尝试编写的示例代码。

主.cpp:

   #include <iostream>
   #include "Arrow.h"
   using namespace std;

   int main()
   {
        Arrow object;
        Arrow *pter = &object;

        object.printCrap(); //Using Dot Access
        pter->printCrap(); //Using Arrow Member Operator
        return 0;
   }

箭头.cpp

   #include <iostream>
   #include "Arrow.h"
   using namespace std;

   Arrow::Arrow()
   {

   }

   void Arrow::printCrap(){
       cout << "Steak!" << endl;
   }

在上面的代码中,它所做的只是使用两种方法(点和箭头)打印牛排。

简而言之,在使用 C++ 编写一个真正的实际应用程序时,我什么时候使用箭头符号?由于我以前的编程经验,我习惯使用点表示法,但箭头对我来说是全新的。

4

3 回答 3

6

在 C 中,a->b精确地等价于(*a).b。为方便起见,引入了“箭头”符号;通过指针访问结构的成员是相当普遍的,箭头符号更容易编写/键入,通常也被认为更具可读性。

不过,C++ 也增加了另一个问题:operator->可以为struct/重载class。尽管在其他方面相当不寻常,但对于智能指针类来说这样做很常见(几乎是必需的)。

这本身并不罕见:C++ 允许重载绝大多数运算符(尽管有些运算符几乎不应该重载,例如operator&&,operator||operator,)。

不寻常的是如何operator->解释重载。首先,虽然a->b看起来像是->一个二元运算符,但当您在 ​​C++ 中重载它时,它被视为一元运算符,因此正确的签名是T::operator(), notT::operator(U)或按该顺序排列的东西。

结果的解释也有些不寻常。假设foo是某种类型的重载对象operator->foo->bar被解释为意义(f.operator->())->bar。这反过来又限制了重载的返回类型operator->。具体来说,它必须返回另一个也重载的类的实例operator->(或对此类对象的引用),否则它必须返回一个指针。

在前一种情况下,看起来简单foo->bar实际上可能意味着“追逐”整个(任意长)对象实例链,每个实例都重载operator->,直到最终到达可以引用名为 的成员bar。对于一个(公认的极端)示例,请考虑以下内容:

#include <iostream>

class int_proxy {
    int val;
public:
    int_proxy(): val(0) {}
    int_proxy &operator=(int n) { 
        std::cout<<"int_proxy::operator= called\n";
        val=n; 
        return *this; 
    }
};

struct fubar {
    int_proxy bar;
} instance;

struct h {
    fubar *operator->() {
        std::cout<<"used h::operator->\n";
        return &instance;
    }
};

struct g {
    h operator->() {
        std::cout<<"used g::operator->\n";
        return h();   
    }
};

struct f {
    g operator->() { 
        std::cout<<"Used f::operator->\n";
        return g();
    }
};

int main() {
    f foo;

    foo->bar=1;
}

尽管foo->bar=1;看起来像是通过指针对成员的简单赋值,但该程序实际上会产生以下输出:

Used f::operator->
used g::operator->
used h::operator->
int_proxy::operator= called

显然,在这种情况下foo->bar甚至接近)等价于简单的(*foo).bar. 从输出中可以明显看出,编译器生成“隐藏”代码以遍历->各种类中的整个重载运算符系列,以获取foo(指向)具有名为的成员bar(在本例中也是一个类型重载operator=,所以我们也可以看到赋值的输出)。

于 2014-01-14T07:21:37.653 回答
3

好问题,

Dot(.) 此运算符用于访问成员函数或有时使用该类/结构的实例变量访问类或结构的数据成员。

object.function(); 
object.dataMember; //not a standard for class.

箭头(->)此运算符用于访问成员函数或有时访问类或结构的数据成员,但使用该类/结构的指针。

ptr->function();
ptr->datamember; //not a standard for class.
于 2012-10-23T04:04:25.513 回答
2

-> 运算符是一种调用被取消引用的指针的成员函数的方法。它也可以写成 (*pter).printCap()。如果没有课程或书籍,C++ 很难学习,所以我建议你买一本,这将是一项很棒的投资!

于 2012-10-23T03:59:13.397 回答