转换构造函数和类型转换函数何时可以同时存在?

双目重载运算符为全局函数时,类的类型转换函数、类的转换构造函数不能同时出现

#include <iostream>
using namespace std;
class Complex
{
public:
    Complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {}   //转换构造函数
    operator double() { return real; }//类型转换函数
    friend Complex operator+ (Complex c1,Complex c2); //重载运算符“+”
    void display();
private:
    double real;
    double imag;
};
Complex operator + (Complex c1, Complex c2)//运算符“+”重载函数为全局函数
{
    return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
void Complex::display()
{
    cout << "(" << real << "," << imag << "i)" << endl;
}
int main()
{
    Complex c1(3, 4), c3;
    c3 = c1 + 2.5;
    //此时编译器有两种转换方案
    // 调用类型转换函数 c3=Complex::operate doule(&c1)+2.5
    // 调用转换构造函数和重载运算符+函数 c3=operate+(c1,Complex(2.5))
    // 出现了二义性,所以编译器报错。
    c3.display();
    return 0;
}

 

 

 

当双目重载运算符函数为全局函数时,如何实现双向赋值,且加法运算可以实现交换律呢?

很简单,增加一个普通的成员函数即可, complex 类使用 real() 和 imag() 函数来获取复数的实部和虚部。

#include <iostream >
using namespace std;
class Complex
{
public:
    Complex(double real = 0.0, double imag = 0.0) :
        m_real(real), m_imag(imag) {
        cout << "Complex(double real = 0.0, double imag = 0.0) " <<this->m_real<< endl;
    }
    // 既有构造函数作用,也有转换构造函数的作用
    Complex(const Complex& c)
    {
        m_real = c.m_real;      m_imag = c.m_imag;
        cout << "Complex(const Complex& c) " <<this->m_real<< endl;
    }
    friend ostream & operator<<(ostream &out, Complex &c);
    friend Complex operator+(const Complex &c1, const Complex &c2);
    double real() const { return m_real; }  //得到Complex对象的实部
    double imag() const { return m_imag; }  //得到Complex对象的虚部
    ~Complex() { cout << "~Complex() " << this->m_real<< endl; }
private:
    double m_real;
    double m_imag;
};

ostream & operator<<(ostream &out, Complex &c)
{
    out << c.m_real << " + " << c.m_imag << "i";;
    return out;
}

Complex operator+(const Complex &c1, const Complex &c2)
{
    cout << "operator+(const Complex &c1, const Complex &c2)" << endl;
    Complex c;
    c.m_real = c1.m_real + c2.m_real;
    c.m_imag = c1.m_imag + c2.m_imag;
    return c;
}

int main()
{
    Complex c1(24.6, 100);
    c1 = 78.4;                     //相当于c1=Complex(78.4);
    double f = c1.real();          //左右类型相等
    f = 12.5 + c1.real();         //左右类型相等
    f = c1.real() + 12.5;         //左右类型相等
    Complex c2 = c1 + 46.7;        //相当于c2=operator+(c1,Complex(46.7))
    f = c1.real() + 46.7;         //左右类型相等
    cout << c2 << endl;
    return 0;
}
运行结果:
Complex(double real = 0.0, double imag = 0.0) 24.6
Complex(double real = 0.0, double imag = 0.0) 78.4
~Complex() 78.4
Complex(double real = 0.0, double imag = 0.0) 46.7
operator+(const Complex &c1, const Complex &c2)
Complex(double real = 0.0, double imag = 0.0) 0
Complex(const Complex& c) 125.1
~Complex() 125.1
~Complex() 46.7
125.1 + 0i
~Complex() 125.1
~Complex() 78.4

 

双目重载运算符为成员函数时,类型转换函数和转换构造函数可以同时存在,且实现双向赋值,加法运算可以实现交换律,但是有趣的时编译器由始自终不会调用重载运算符函数。

在加法运算中,编译器一直在把Complex类对象转化为double类,来进行加法运算。

#include<iostream>
using namespace std;
class Complex
{
public:
    Complex(double real = 0.0, double imag = 0.0) :m_real(real), m_imag(imag)
    {
        cout << "Complex(double real = 0.0, double imag = 0.0) " <<this->m_real<< endl;
    }
    Complex(const Complex& c)
    {
        m_real = c.m_real;      m_imag = c.m_imag;
        cout << "Complex(const Complex& c)" <<this->m_real<< endl;
    }
    friend ostream& operator<<(ostream& out, Complex& c);
    operator double() const
    {
        cout << "double() const " <<this->m_real<< endl;  return m_real;  //
    }
    Complex operator+(Complex& c)
    {
        Complex c1;   c1.m_real = m_real + c.m_real;
        c1.m_imag = m_imag + c.m_imag;  cout << "operator+(Complex& c)" << endl;
        return c1;
    }
    ~Complex() { cout << "~Complex()" <<this->m_real<< endl; }
private:
    double m_real; double m_imag;
};
ostream& operator<<(ostream& out, Complex& c)
{
    out << c.m_real << "+" << c.m_imag << "i";
    return out;
}

int main()
{
    Complex c1(24.6, 100);
    c1 = 78.4;              //相当于c1=Complex(78.4);
    double f = c1;          //相当于f=Complex::double(&c1)
    f = 12.5 + c1;          //相当于f=12.5+Complex::double(&c1)
    f = c1 + 12.5;          //相当于f=Complex::double(&c1)+12.5
    Complex c2 = c1 + 46.7; //相当于c2=Complex(Complex::double(&c1)+46.7)
    cout << c2 << endl;
    return 0;
}
运行结果:
Complex(double real = 0.0, double imag = 0.0) 24.6
Complex(double real = 0.0, double imag = 0.0) 78.4
~Complex()78.4
double() const 78.4
double() const 78.4
double() const 78.4
double() const 78.4
Complex(double real = 0.0, double imag = 0.0) 125.1
125.1+0i
~Complex()125.1
~Complex()78.4

 

 

 使用explicit将这两种转换,变成显式转换,就可设置可调用运算符“+”重载函数的语句

#include<iostream>
using namespace std;
class Complex
{
public:
    explicit Complex(double real = 0.0, double imag = 0.0) :m_real(real), m_imag(imag)
    {
        cout << "Complex(double real = 0.0, double imag = 0.0)" <<" "<< this->m_real <<endl;
    }
    Complex(const Complex& c)
    {
        m_real = c.m_real;      m_imag = c.m_imag;
        cout << "Complex(const Complex& c)" << endl;
    }
    friend ostream& operator<<(ostream& out, Complex& c);
    explicit operator double() const
    {
        cout << "double() const" << endl;  return m_real + 10;  //
    }
    Complex operator+(Complex& c)
    {
        Complex c1;   
        c1.m_real = m_real + c.m_real;
        c1.m_imag = m_imag + c.m_imag;  
        cout << "operator+(Complex& c)" << endl;
        return c1;
    }
    ~Complex() { cout << "~Complex()" <<this->m_real<< endl; }
private:
    double m_real; double m_imag;
};
ostream& operator<<(ostream& out, Complex& c)
{
    out << c.m_real << "+" << c.m_imag << "i";
    return out;
}

int main()
{
    Complex c1(24.6, 100);
    c1 = Complex(78.4);              //相当于c1=Complex(78.4);
    Complex c2 = c1 + Complex(46.7); //相当于c2=c1.operator+(Complex(46.7))
    cout << c2 << endl;
    return 0;
}
运行结果:
Complex(double real = 0.0, double imag = 0.0) 24.6
Complex(double real = 0.0, double imag = 0.0) 78.4
~Complex()78.4
Complex(double real = 0.0, double imag = 0.0) 46.7
Complex(double real = 0.0, double imag = 0.0) 0operator+(Complex& c)
Complex(const Complex& c)
~Complex()125.1
~Complex()46.7
125.1+0i
~Complex()125.1
~Complex()78.4

 

posted @ 2020-05-29 19:59  jpbk  阅读(121)  评论(0)    收藏  举报