使用转换运算符对类对象进行引用

cout a class object using conversion operator

本文关键字:对象 引用 转换 运算符      更新时间:2023-10-16
#include <iostream>
#include <cmath>
using namespace std;
class Complex
{
private:
    double real;
    double imag;
public:
    // Default constructor
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i)
    {}
    // magnitude : usual function style
    double mag()
    {
        return getMag();
    }
    // magnitude : conversion operator
    operator int ()
    {
        return getMag();
    }
private:
    // class helper to get magnitude
    double getMag()
    {
        return sqrt(real * real + imag * imag);
    }
};
int main()
{
    // a Complex object
    Complex com(3.0, 4.0);
    // print magnitude
    cout << com.mag() << endl;
    // same can be done like this
    cout << com << endl;
}

我不明白编译器如何解析调用转换运算符以进行cout << com << endl;.

我还可以在同一类中有多个转换运算符。在这种情况下,将如何解决?

您已向 int 声明了一个转换运算符。由于此运算符不是显式的,因此编译器在查找 ostream::operator<< 的最佳重载时会考虑它。请记住,C++编译器始终尝试自动转换类型以查找匹配的调用,包括转换构造函数、转换运算符和隐式类型转换。

如果您不希望此行为,则可以从 C++11 开始将运算符标记为 explicit

explicit operator int() {
     return getMag();
}

关于问题的第二部分,如果有多个同样好的转换,则会调用编译错误。如果你添加了,比如说,operator double,那么当存在ostream::operator(double)时,调用将是不明确的,你需要com转换为你想要的类型。

我假设编译器尝试转换为 cout 定义了重载的类型。如果可以将其转换为 cout 定义了重载的 2 种类型,则会出现编译错误。如果将此函数添加到类代码中,则不会编译:

// magnitude : conversion operator
operator float ()
{
    return getMag() + 1;
}

要解决这个问题,你必须做这样的强制转换:

// same can be done like this
cout << "Com: " << (float) com << endl;