查询C++中的重载<<运算符

Query on overloading << operator in C++

本文关键字:lt 运算符 重载 C++ 查询      更新时间:2023-10-16

下面是我的程序,它给出了以下错误

c:mystuff>cl dummy.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.
dummy.cpp
c:Program Files (x86)Microsoft Visual Studio 10.0VCINCLUDExlocale(323) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc
dummy.cpp(20) : error C2143: syntax error : missing ';' before '&'
dummy.cpp(20) : error C4430: missing type specifier - int assumed. Note: C++ doe
s not support default-int
dummy.cpp(20) : error C2061: syntax error : identifier 'ostream'
dummy.cpp(20) : error C4430: missing type specifier - int assumed. Note: C++ doe
s not support default-int
dummy.cpp(20) : error C2805: binary 'operator <<' has too few parameters
dummy.cpp(20) : error C2333: 'Complex::operator <<' : error in function declarat
ion; skipping function body
dummy.cpp(32) : error C2065: 'cout' : undeclared identifier



#include<iostream> 
class Complex{
private:
    double real;
    double imag;
public:
    Complex(double real, double imag){
        this->real = real;
        this->imag = imag;
    }
    Complex operator+ (const Complex& Operand){
        double real = this->real + Operand.real;
        double imag = this->imag + Operand.imag;
        return Complex(real,imag);
    }
    ostream &operator<< (ostream  &o, Complex Operand){//line 20
        o  << Operand.real;
        o  << Operand.imag;
        return o;
    }
};
int main(){
    Complex c1(1,2);
    Complex c2(3,4);
    Complex c3 = c1 + c2;
    cout << c3;

}

我的问题:

1)

在第32行,通过包括来自iostream的外部对象cout,可以看到cout,那么,第32行cout << c3出错的原因是什么?

2)

请帮助我理解第20行出现错误的原因。operator<<方法只是从书中复制的。此外,我还想了解为什么我们应该在operator<<方法中传递ostream引用作为第一个形式参数。因为,在operator+方法中,通过使用this访问第一个操作数对象,我只使用了一个操作数作为形式参数。我不能用thisoperator<<方法做同样的事情吗?

您已经将运算符声明为成员函数。这意味着它必须在LHS上的Complex实例上操作,并且参数太多。你需要的是让它成为非会员。实现这一点并允许操作员访问Complex的非公共成员的一种方法是在Complex类定义中将其声明为friend

friend std::ostream& operator << (std::ostream & o, const Complex& Operand){
    o  << Operand.real;
    o  << Operand.imag;
    return o;
}

除此之外,ostream位于std名称空间中,因此将其称为std::ostream(代码中其他地方的cout也是如此)

请注意,这里我还通过const引用传递Operand,因为您不需要副本。

你对Complex operator+ (const Complex& Operand)也有同样的问题。

您必须指定名称空间,其中定义了名称cout和ostream。例如

std::ostream &operator<< (std::ostream  &o, Complex Operand){//line 20
    o  << Operand.real;
    o  << Operand.imag;
    return o;
}
std::cout << c3;

或者你可以包括指令

using namespace std;

在包含的标头之后。或者你可以使用声明

using std::ostream;
using std::cout;

当使用限定名称时,首选第一种方法。

此外,operator <<必须定义为朋友函数

friend std::ostream &operator<< (std::ostream  &o, const Complex &Operand){//line 20
    o  << Operand.real;
    o  << Operand.imag;
    return o;
}

因此该类可以定义为

class Complex{
private:
    double real;
    double imag;
public:
    Complex(double real, double imag){
        this->real = real;
        this->imag = imag;
    }
    Complex operator+ (const Complex& Operand) const {
        double real = this->real + Operand.real;
        double imag = this->imag + Operand.imag;
        return Complex(real,imag);
    }
    friend std::ostream &operator<< (std::ostream  &o, const Complex &Operand){//line 20
        o  << Operand.real;
        o  << Operand.imag;
        return o;
    }
};

要正确重载<lt;操作员,您必须在类之外编写一个函数

ostream &operator<< (ostream &o, Complex Operand){
    o  << Operand.real;
    o  << Operand.imag;
    return o;
}

然后将其声明为类内的朋友

friend ostream &operator<< (ostream &, Complex);

此外,我相信你想输出这样的东西:

o << Operand.real << " + " << Operand.imag << "i";

另外,尝试使用

using namespace std;

在包含行之后,如ostream和许多其他c++特性都在std命名空间中。