使用转换运算符

时间:2016-07-06 13:25:23

标签: c++

#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;的转换运算符。

我也可以在同一个类中拥有多个转换运算符。在这种情况下如何处理决议?

2 个答案:

答案 0 :(得分:9)

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

如果您不想要这种行为,那么从C ++ 11开始,您可以将运算符标记为explicit

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

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

答案 1 :(得分:0)

我认为编译器试图转换为cout已定义过载的类型。 如果它可以转换为cout定义了过载的2种类型,则会出现编译错误。 如果将此函数添加到类代码中将无法编译:

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

要解决这个问题,你必须做这样的演员:

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