重载提取和插入<< >> operator c ++

时间:2015-12-11 09:48:49

标签: c++

我一直试图重载<< (cout)和>> (cin)运算符现在有一段时间用于一类复数,我在.h文件中给出了原型。

这是我尝试在class.cpp文件中执行此操作:

std::istream &operator>> (std::istream &in, complex& c) {
    double h, j;
    in >> h >> j;

    c.set(h,j);

    return in;
}

std::ostream &operator<<(std::ostream &out, complex c) {
    out << c.getReal;
    out << c.getImag;

    return out;
}
  1. 这是我第一次见到std:: istreamstd:: ostream而不是cout和cin,我不确定cout <<和{{1}都是相关的

  2. 我尝试在main.cpp文件上测试它,但是我收到了错误

  3. cin >>应该将复杂的参数吸收到复杂的类参数中,并更改私有成员的值>>real

  4. 不确定我是否应该在这里使用我的设置功能

  5. 这是我给出的原型.h文件:

    imag

    有人可以告诉我如何适当地超载吗?

    好的,我现在正在尝试输出a + bi:

    #ifndef COMPLEX_H
    #define COMPLEX_H
    
    
    class complex {
    
    public:
        complex();
        complex(double a);
        complex(double a, double b);
        complex(int a, int b);
        void print() const;
        void set(double a = 0, double b = 0);
        void set(int a = 0, int b = 0);
        double getReal() const;
        double getImag() const;
        void get(double&, double&) const;
    
        complex operator+ (double& x);
        complex operator+ (complex&);
        complex operator+= (complex&);
        complex operator+= (int&);
        complex operator++ (int);
        complex operator++ ();
        complex operator- (double&);
        complex operator- (complex&);
        complex operator-= (complex&);
        complex operator-= (double&);
        complex operator-- (int);
        complex operator-- ();
        complex operator* (complex&);
        complex operator* (double&);
        complex operator*= (complex&);
        complex operator*= (double&);
        complex operator/ (complex&);
        complex operator/= (complex&);
        complex operator/= (double);
        complex operator/ (double);
        void operator= (const complex&);
        bool operator== (complex&);
        bool operator!=(complex &c);
    
        friend std::istream &operator>> (std::istream &in, complex& c);
        friend std::ostream &operator<<(std::ostream &out, complex c);
    
        /*complex conj() const;
        double norm() const;
        double modulus() const;
        */
    private:
        double real;
        double imag;
    };
    
    #endif // COMPLEX_H
    

    并输入:

    std::ostream& operator<< (std::ostream& out, complex const& c) {
        return out << c.getReal() << "+" << c.getImag() << "i";
    }
    

    但是编译时出现以下错误:

    这是我的complex.cpp文件(类复杂实现文件)的第181行,其中std::istream& operator>> (std::istream& in, complex& c) { double h, j; if (in >> h >> "+" >> j >> "i") { c.set(h, j); } return in; } 位于上面的函数定义中:

    if (in >> h >> "+" >> j >> "i") {

    以下是我的complex.h文件中第45行(注意每个错误是单独的,总共7行),其中binary '>>': no operator found which takes a right-hand operand of type 'const char [2]' (or there is no acceptable conversion) 原型所在。

    friend std::istream &operator>> (std::istream &in, complex& c);

    以下是我的complex.h文件的第46行

    'istream':is not a member of 'std'
    
    syntax error missing ';' before '&'
    
    'istream':'friend' not permitted on data declarations
    
    missing type specifier-int assumed. Note:C++ does not support default-int
    
    unexpected token(s) preceding';'
    
    
    namespace "std" has no member "istream"
    
    namespace "std" has no member "istream"
    

    位于

    friend std::ostream &operator<<(std::ostream &out, complex c);
    

    我注意到两者都是同一类型的错误。注意我有

    'ostream': is not a member of 'std'
    
    syntax error: missing ';' before '&'
    
    'ostream':'friend' not permitted on data declarations
    
    missing type specifier -int assumed.Note: C++ does not support default-int
    
    unexpected token(s) preceding ';'
    
    namespace "std" has no member "ostream"
    
    namespace "std" has no member "ostream"
    

    在complex.cpp文件和main.cpp文件

1 个答案:

答案 0 :(得分:6)

让我们从简单的东西开始:std::cin是从std::istream派生的类型的实例。同样,std::cout是从std::ostream派生的类型的实例。这些流类型用于为输入和输出操作符重载(并且尝试从它们派生以改变它们的行为 - 使用{{1}完成的操作})。还有其他流类型,例如std::streambuf / std::ifstream(读取/写入文件)和std::ofstream / std::istringstream(读取/写入字符串)。

接下来要看的是输出操作符:对于初学者,在调用成员函数时需要括号。您还需要在两个值之间使用分隔符,否则实部和虚部可能相互融合。我可能会将操作符实现为

std::ostringstream

使用空格而不使用其他分隔符通常可能不是最理想的,但会使阅读更容易。对于复杂类的实际实现,我可以使用格式编写 real std::ostream& operator<< (std::ostream& out, complex const& value) { return out << value.getReal() << " " << value.getImag(); } imag +i real ( imag ,但这些内容难以解析。

在尝试读取值之后,应该从流中读取值始终。例如,代码可能如下所示:

)

除了丢失的检查外,输入函数看起来没问题,假设两个值之间用空格分隔:在尝试读取值之前,默认情况下会使用输入运算符跳过空格。如果使用某些分隔符将值格式化得更加精美,则需要单独处理这些分隔符。这样做的代码可能如下所示:

std::istream& operator>> (std::istream& in, complex& c) {
    double h, j;
    if (in >> h >> j) {
        c.set(h, j);
    }
    return in;
}

这些看起来很滑稽的实体template <char C> std::istream& skip_char(std::istream& in) { if ((in >> std::skipws).peek() != C) { in.setstate(std::ios_base::failbit); } else { in.ignore(); } return in; } std::istream& (*const open_parenthesis)(std::istream&) = &skip_char<'('>; std::istream& (*const close_parenthesis)(std::istream&) = &skip_char<')'>; std::istream& (*const comma)(std::istream&) = &skip_char<','>; std::istream& operator<< (std::istream& in, complex& c) { double real, imag; if (in >> open_parenthesis >> real >> comma >> imag >> close_parenthesis) { c.set(real, imag); } return in; } open_parenthesisclose_parenthesis是初始化为指向函数模板comma实例的函数指针。他们有一个特定的签名,使他们有资格成为操纵者。当&#34;读入&#34;一个操纵器,相应的函数被调用它们是&#34;读&#34;从。也就是说,例如skip_char会产生一个呼叫std::cin >> comma,这实际上是对comma(std::cin)的呼叫。但是,我想对于这项任务,全面的方法有点矫枉过正。