【问题标题】:How to create endl manipulator for my class?如何为我的班级创建 endl 操纵器?
【发布时间】:2013-05-25 02:51:14
【问题描述】:

我的班级看起来像:

class FileOut
{
private:
    std::ofstream stream;
public:
    FileOut(string sciezka);
    ~FileOut(void);

    friend FileOut & operator<< (FileOut & obiekt, const char* w);
    friend FileOut & operator<< (FileOut & obiekt, const string & w);
    friend FileOut & operator<< (FileOut & obiekt, const char & znak);
    friend FileOut & operator<< (FileOut & obiekt, const int & liczba);
    friend FileOut & operator<< (FileOut & obiekt, const double & liczba);
    friend FileOut & operator<< (FileOut & obiekt, std::endl);
    //friend FileOut & endl (FileOut & obiekt);
};

operator&lt;&lt; 适用于字符串、char、int 等(我将新字符放入stream)。 我想为我的班级实现操纵器endl。通常我们这样覆盖它:

ostream &amp; endl (ostream &amp; os){ return os &lt;&lt; '\n'; }

但它不适用于我的班级。我声明了

friend FileOut &amp; endl (FileOut &amp; obiekt);

但它不起作用。我该怎么做才能写:

FileOut save("file.txt");
save<<"tralalala"<<endl<<1123;

???

【问题讨论】:

  • this question/answer 是否与您尝试做的类似?或者this one
  • 什么'不起作用'?您是否遇到编译器错误、意外输出、电视随机内爆?
  • 1) 错误 C2679:二进制“

标签: c++ stream overriding endl


【解决方案1】:

由于std::eol其实是一个兼容ostream&amp; (*fctr) (ostream&amp;)类型的函数模板,所以需要重载如下操作符:

class FileOut
{
//...    
friend FileOut & operator<< (FileOut & obiekt, ostream& (*fctr) (ostream&))
//...
};

在重载中,您需要确保 fctr 确实与 eol 匹配(可以是 eof、tab 或任何匹配签名的操纵器),然后将您想要写入的任何内容写入 eol 上的文件:

#include <fstream>
#include <string>
#include <iostream>

using namespace std;

class FileOut
{
private:
    std::ofstream stream;
public:
    FileOut(std::string sciezka):stream(sciezka) {};
    ~FileOut(void){};

    friend FileOut & operator<< (FileOut & obiekt, const char* w) {obiekt.stream<<w;return obiekt;} ;
    friend FileOut & operator<< (FileOut & obiekt, const string & w);
    friend FileOut & operator<< (FileOut & obiekt, const char & znak);
    friend FileOut & operator<< (FileOut & obiekt, const int & liczba){obiekt.stream<<liczba;return obiekt;};
    friend FileOut & operator<< (FileOut & obiekt, const double & liczba);
    friend FileOut & operator<< (FileOut & obiekt, ostream& (*pf) (ostream&));
    //friend FileOut & endl (FileOut & obiekt);
};

FileOut & operator<< (FileOut & obiekt, ostream& (*pf) (ostream&))
{
    if(pf==&std::endl)
    {
        obiekt.stream<<"MY FAT JUICY EOL";
    }

    return obiekt;
}

int main(int argc, char* argv[])
{
    FileOut save("file.txt");

    save<<"tralalala"<<endl<<1123;
    return 0;
}

【讨论】:

    【解决方案2】:

    或者,如果您不喜欢使用 std::eol 并想要自己的:

    #include <fstream>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    class FileOut
    {
    private:
        std::ofstream stream;
    public:
        FileOut(std::string sciezka):stream(sciezka) {};
        ~FileOut(void){};
    
        friend FileOut & operator<< (FileOut & obiekt, const char* w) {obiekt.stream<<w;return obiekt;} ;
        friend FileOut & operator<< (FileOut & obiekt, const string & w);
        friend FileOut & operator<< (FileOut & obiekt, const char & znak);
        friend FileOut & operator<< (FileOut & obiekt, const int & liczba){obiekt.stream<<liczba;return obiekt;};
        friend FileOut & operator<< (FileOut & obiekt, const double & liczba);
        friend FileOut & operator<< (FileOut & obiekt, void (*pf) ());
    
        static void eol() {};
        //friend FileOut & endl (FileOut & obiekt);
    };
    
    FileOut & operator<< (FileOut & obiekt, void (*pf) ())
    {
        if(pf == FileOut::eol)
        {
            obiekt.stream<<"MY FAT JUICY STATIC EOL";
        }
    
        return obiekt;
    }
    
    int main(int argc, char* argv[])
    {
        FileOut save("file.txt");
    
        save<<"tralalala"<<FileOut::eol<<1123;
        return 0;
    }
    

    【讨论】:

    • 这对我来说通常很复杂,但是您显示的代码很短而且还可以。两个版本都有效。我认为替代形式更好,但我不想仅使用它的形式,因为我必须写 FileOut::endl 而不仅仅是 endl - 这很不方便。但是当我编译第一个版本(在 Visual Studio 2012 中)时,我得到“错误”:IntelliSense:无法确定重载函数“std::endl”的哪个实例是预期的。但是程序编译并正常工作,我想:) 非常感谢!
    • @Danu:是的,看起来 IntelliSense 仍在追赶 C++ 11,因为我得到了同样的结果。我很高兴您喜欢这些答案,请投票和/或接受最适合您的答案,或两者兼而有之:)谢谢!
    猜你喜欢
    • 2014-01-07
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    • 2018-10-27
    相关资源
    最近更新 更多