gpt4 book ai didi

c++ - C++ 中的箭头成员运算符

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:19:28 26 4
gpt4 key购买 nike

我对使用 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++ 编写真正的实际应用程序时,我什么时候使用箭头符号?由于我以前的编程经验,我习惯使用点符号,但箭头对我来说是全新的。

最佳答案

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

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

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

不同寻常的是如何解释重载的 operator->。首先,尽管 a->b 看起来像 -> 是二元运算符,但当您在 ​​C++ 中重载它时,它会被视为一元运算符,因此正确的签名是 T::operator(),而不是 T::operator(U) 或该顺序上的其他内容。

结果的解释也有些不寻常。假设 foo 是重载 operator-> 的某种类型的对象,foo->bar 被解释为 (f.operator ->())->栏。这反过来又限制了重载 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= 的类型,因此我们也可以看到赋值的输出)。

关于c++ - C++ 中的箭头成员运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13023320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com