转换构造函数和类型转换函数何时可以同时存在?
双目重载运算符为全局函数时,类的类型转换函数、类的转换构造函数不能同时出现
#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

浙公网安备 33010602011771号