过载移位算子<<允许链接

时间:2013-07-22 08:22:45

标签: c++ operator-overloading chaining

我正在努力解决运算符重载问题,因为我希望它允许链接

class A{
 int a;
public:
 void doSomething(char *str);
 A operator<<(char *str);
}

所以我有这门课,我能做的就是拿一个字符串做一些事情,这对这个问题并不重要。

我现在能做的是

A *counter = new A();
counter->doSomething("hello");

如果我实现了重载的移位运算符

A A::operator<<(char *str)
{
  this->doSomething(str);
  return this;
}

我能够像这样写

A *counter = new A();
(*counter) << "hello";

我希望我在这里没有犯错,因为现在我想知道如何允许链接

(*counter) << "hello" << "test";

我知道通过链接可以做到这一点

(*counter).operator<<("hello" << "test");

这显然没有任何意义,因为有两个字符串/ char数组 但我知道有办法做到这一点。我搜索了它,但每个问题只是关于将相同类型的实例链接在一起

然后我尝试将两个参数添加到函数中并将其添加为朋友...我不确定但是我可能需要使用类型char*或流对象创建一个新的重载运算符把它作为A的朋友?

感谢您的帮助,我想应该有一个我现在看不到的简单答案。

4 个答案:

答案 0 :(得分:5)

您需要返回*this的引用,因此您的返回类型必须为A&

A& operator<<(char *str)
{
  this->doSomething(str); // as before
  return *this;           // return reference to this instance.
}

答案 1 :(得分:2)

您的问题中有两个错误的假设我想澄清。

  1. 如果要在指针上调用operator<<,则必须执行此操作 每次通话,不仅仅是第一次。这就是为什么

    A *counter = new A();
    (*counter) << "hello";
    

    有效,但

    (*counter) << "hello" << "test";
    

    没有。第二个operator<<将在指针上调用 由第一个返回,这不是你想要的。你必须写 (这很难看):

    (*((*counter) << "hello")) << "test";
    
  2. 可以链接移位运算符,然后从左到右进行求值 对,这就是为什么以下是另一个错误的假设:

    A << "hello" << "test";
    
         

    我知道通过链接可以做到这一点

    A.operator<<("hello" << "test");
    

    它实际上是这样评估的:

    A.operator<<("hello").operator<<("test");
    

    更详细:

    ( A.operator<<("hello") ).operator<<("test");
    
  3. 如果operator<<返回的对象也可以链接运算符 实现operator<<,因此您可以返回*this的副本 属于A类型。但是,这将复制对象 不必要的,因为它很可能只是非常活着 暂时只能由以下操作员使用一次。

    所以你要做的是在operator<<中返回一个引用,可以在其上调用下一个operator<<。这样可以避免复制:

    A& operator<<(char *str)
    {
        this->doSomething(str);
        return *this;
    }
    

    如上所述,返回指针是可能的,但不会产生您想要的结果。语法会非常难看。

答案 2 :(得分:1)

operator <<应返回链接参考。

A& operator<<(char *str);

A& A::operator<<(char *str)
{
  this->doSomething(str);
  return *this;
}

应该像

一样使用
A counter;
counter << "hello" << "test";

答案 3 :(得分:0)

A *counter = new A();

使你的'计数器'成为一个指针,而不是一个对象。要在A上使用运算符,您可以使用

(*counter) << "hello" 

此外,我建议你再考虑一下运算符的重载问题。虽然起初它通常看起来很酷,但它很容易导致难以理解和维护的代码。