C++ 重载运算符 '>>'

Posted

技术标签:

【中文标题】C++ 重载运算符 \'>>\'【英文标题】:C++ overload operator '>>'C++ 重载运算符 '>>' 【发布时间】:2014-01-14 07:32:54 【问题描述】:

我一直在查看许多不同的示例和解释,但没有一个能够真正回答我正在寻找的内容。我有三个类,每个类都有一个名为 connect 的方法:

class foo  ... 
void foo::connect(bar br)  ... 

class bar  ... 
bar& bar::connect(baz bz)  ... 

class baz  ... 
baz& baz::connect()  ... 

在我的主课中,我像这样“连接”它们:

foo.connect(bar);
bar.connect(baz);
baz.connect();

或:

foo.connect( bar.connect( baz.connect() ) );

(我知道这只是简单的解释,如果需要我可以更好地解释)

所以,我试图重载运算符“>>”,以便在主函数中包含类似的内容:

foo >> bar >> baz;

对于第一个运算符,它可以工作,所以如果我简单地执行以下操作,它就可以正常工作:

foo >> bar.connect(baz.connect);

但是,当我设置另一个 '>>' 运算符 g++ 返回此错误:

error: no match for ‘operator>>’ in ‘operator>>((* & foo), (* & bar)) >> baz.baz::connect()’

我认为我没有正确地重载运算符“>>”:

bar& operator>> (bar &br, baz &bz)

  ...

感谢您的帮助:)

【问题讨论】:

注意,不建议使用>>进行非流和非位移操作。 对,但我在操作符 '>' 上遇到了更多问题,所以我开始尝试这个,看起来它正在工作。无论如何,也许这不是一个好主意。谢谢! 【参考方案1】:

运算符并不是什么神奇的东西:它们只是以一种有趣的方式拼写的函数。也就是你的说法

foo >> bar >> baz;

实际上只是调用[或尝试调用]

operator>> (operator>> (foo, bar), baz);

也就是说,你需要操作符

bar& operator>> (foo& f, bar& b) 
    f.connect(b);
    return b;

bar& operator>> (bar& b0, baz& b1) 
    return b0.connect(b1);

注意,最后一个connect() 不能使用operator>>(),因为该运算符总是需要两个参数。

【讨论】:

您对接线员的通话是正确的>>。我以前没有这样想过,现在我发现这对我来说有点问题。按照你建议的方式去做应该完全可行,问题是我不能那样做。无论如何,我会试一试,让你知道。谢谢!【参考方案2】:

您的重载运算符将bar& 作为其左侧操作数,将baz& 作为其右侧操作数,但您的示例代码:

foo >> bar.connect(baz.connect);

foo& 作为左侧操作数,将bar& 作为右侧操作数。您是否还定义了另一个版本的operator>>

另请注意,引用您的示例代码:

foo.connect(bar);
bar.connect(baz);
baz.connect();

和这个不一样:

foo.connect( bar.connect( baz.connect() ) );

操作顺序不同;在第二个示例中,baz.connect() 首先运行,然后是 bar.connect(),以此类推。这与第一个例子相反。这在您的应用程序中可能无关紧要,但需要考虑。

【讨论】:

我已经为每个类重载了运算符>>,因此它们返回同一类的对象:foo.connect(bar); // returns voidbar.connect(baz); // returns bar&baz.connect(); // returns baz& 这是有意完成的,因此我可以使用运算符>>,所以foo >> bar.connect(baz.connect()); 实际上是foo >> bar_object_returned;顺便说一句,效果很好。问题是当我有foo >> bar >> baz 时,它说我实际上在做(foo >> bar) >> baz,但它并没有抱怨(foo >> bar) 返回无效。就是这么说的。 顺便说一句,我完全同意这两种符号之间的区别,这是我直到现在才意识到的。谢谢!【参考方案3】:

虽然您没有展示它,但有证据表明您的其他操作员是问题所在。它看起来像这样:

foo& operator>>(foo&, bar&)  ... 

但是为了让它起作用:

foo >> bar >> baz;

您可能希望foo >> bar 返回bar(而不是foo),这样下一个调用就是这个函数:

??? operator>>(bar&, baz&)  ... 

为了保持一致性,这可能应该返回baz&,尽管在这种情况下并不是绝对必要的。

你拥有它的方式(因为foo >> bar 返回foo),第二个operator>> 试图调用这个(我假设不存在)函数:

??? operator>>(foo&, baz&)  ... 

【讨论】:

我没有第一个运算符,但我发现您所说的 foo >> bar 在这种情况下返回“bar”而不是“void”很有趣。我会试着走那条路。谢谢!

以上是关于C++ 重载运算符 '>>'的主要内容,如果未能解决你的问题,请参考以下文章

C++ 运算符重载

C++:使用类|| 运算符重载友元

C++ 作业 - 使用动态数组重载 >> 运算符

C++ 输入/输出运算符重载

c++重载运算符两种形式的选择

C++ - 为我的字符串类重载运算符>>