【问题标题】:Trying to overload cout << operator but its not working试图重载 cout << 运算符但它不起作用
【发布时间】:2012-01-31 06:26:35
【问题描述】:

我在这里从课堂上剪掉了不相关的部分。我不知道我做错了什么,只是想能够 cout

#include <iostream>

class Snipped
{

    public:
        friend std::ostream& operator<<(std::ostream& os, const Snipped& s);

    protected:
    private:
};

std::ostream& operator<<(std::ostream& os, const Snipped& s)
{
    os << "test";
    return os;
}

int main(int argc, char* argv[])
{
    Snipped* s = new Snipped();

        std::cout << s << std::endl << s;

    delete s;
    return 0;
}

预期输出:

test
test

实际输出:

0x12ae20
0x12ae20  (random memory location?)

【问题讨论】:

    标签: c++ overloading operator-keyword


    【解决方案1】:
    std::cout << s << std::endl << s;      
    

    您正在使用地址调用&lt;&lt;,您需要使用Snipped 类型的对象调用它。
    上面的代码行不会调用您的重载运算符函数,因为重载函数的参数不匹配。

    您需要致电:

    std::cout << *s << std::endl << *s;      
    

    这可确保调用您的 &lt;&lt; 重载运算符函数,因为参数与之匹配。

    【讨论】:

      【解决方案2】:

      试试

      std::cout << *s << std::endl; 
      

      顺便说一句,

      std::cout << s << std::endl; 
      

      并不是真正的随机内存位置。

      在这种情况下,它是堆上的实际内存地址。

      您实际上可以使用该地址来检查对象的身份。

      这在调试或实际代码中很有用。 例如,如果您查看赋值运算符,您会经常看到:

      class Foo
      {
        Foo& operator=( const Foo& foo )
        {
          // use the identity principle 
          if ( &foo==this )
            return *this;  // so I don't waste CPU cycles copying to myself
      
          // ...really do copy here
          return *this;
        }
      };
      

      【讨论】:

      • 你可能指的是=而不是==,我希望这个例子仅用于演示。如果重载复制分配我宁愿推荐Copy and Swap Idiom而不是身份检查的开销。
      【解决方案3】:

      虽然只是取消引用指针(即使用 '*s' 而不是 's'),但还有一条更大的鱼要炸!除非有充分的理由将对象放在堆上,否则您不应该这样做:

      int main()
      {
          Snipped s;
          std::cout << s << '\n' << s;
      }
      

      我发现new 和更多delete 的使用在我编写的程序中非常少见。除了更简单的代码之外,这通常还可以方便地产生更快的程序。如果你真的需要在堆上分配一些东西,使用某种智能指针来确保对象被自动释放:

      int main()
      {
          std::unique_ptr<Snipped> s(new Snipped);
          std::cout << *s << '\n' << *s;
      }
      

      附带说明,除非您真的打算刷新流,否则不要使用std::endl:我发现不恰当地使用std::endl 不止一次是导致大量性能问题的根本原因。当然,大多数时候这无关紧要,但在更多情况下,您并不关心同花顺。如果您不喜欢使用'\n'"\n",您可以改用自定义操纵器:

      std::ostream& nl(std::ostream& out) { return out << '\n'; }
      

      有了这个,您可以使用nl 代替std::endl,并且不必总是刷新流。

      【讨论】:

      • +1 用于提及由于endl 导致的性能问题。这是一个经常被忽视的性能问题。对于那些感兴趣的人,C++: “std::endl” vs “\n” 将是一个不错的阅读。
      猜你喜欢
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      相关资源
      最近更新 更多