何为隐式转换?
我的理解是:编译器自动调用某类的构造函数,将其他类转换为此类,以方便明确某些操作。这样说起来比较难理解,直接以例子说明。
先定义一个CMyVector 的 向量类,如下:
.h文件:
class CMyVector {
public:
/*explicit*/ CMyVector(int ix = 0, int iy = 0, int iz = 0); //构造函数,这里注释掉 explicit, 表示允许隐式转换
CMyVector(const CMyVector & other); //拷贝构造函数
~CMyVector(); //析构函数
CMyVector& operator=(const CMyVector &other);
//+操作符重载,注意:返回值必须以值传递的方式, 引用会导致传递局部变量的引用
//一种+号重载的方式 ,默认有个this 成员参数 :a + b, 其中a就为this参数,b为 other参数
CMyVector operator+ (const CMyVector & other);
bool operator==(const CMyVector & other);
void display();
private:
int x, y, z;
};
.cpp文件
#include "MyVector.h"
#include <iostream>
using namespace std;
CMyVector::CMyVector(int ix, int iy, int iz) : x(ix), y(iy), z(iz)
{
cout << "构造函数 CMyVector: x = " << x << "\t y = " << y << "\t z = " << z << endl;
}
CMyVector::CMyVector(const CMyVector & other)
{
x = other.x;
y = other.y;
z = other.z;
cout << "拷贝构造函数 CMyVector: x = " << x << "\t y = " << y << "\t z = " << z << endl;
}
CMyVector::~CMyVector()
{
cout << "析构函数 ~CMyVector: x = " << x << "\t y = " << y << "\t z = " << z << endl;
}
CMyVector& CMyVector::operator=(const CMyVector &other)
{
if (this != &other)
{
x = other.x;
y = other.y;
z = other.z;
}
cout << "赋值函数 operator=: x = " << x << "\t y = " << y << "\t z = " << z << endl;
return *this;
}
CMyVector CMyVector::operator+(const CMyVector & other)
{
CMyVector v1;
v1.x = x + other.x;
v1.y = y + other.y;
v1.z = z + other.z;
cout << "重载操作符 operator+: x = " << v1.x << "\t y = " << v1.y << "\t z = " << v1.z << endl;
return v1;
}
bool CMyVector::operator==(const CMyVector & other)
{
return (x == other.x && y == other.y && z == other.z);
}
CMyVector operator+ (const CMyVector & other1, const CMyVector & other2)
{
CMyVector v1;
v1.x = other1.x + other2.x;
v1.y = other1.y + other2.y;
v1.z = other1.z + other2.z;
cout << "友元1 重载操作符 operator+: x = " << other1.x << "\t y = " << other1.y << "\t z = " << other1.z << endl;
return v1;
}
main函数:
int main()
{
CMyVector d(1);
d = 2.0;
d = d + 3;
d = 4 + d;
std::cout << (d == 9) << std::endl;
system("pause");
return -1;
}
初探隐式转换
调用1:
CMyVector d(2);
d = d + 3; //相当于调用 d = d + CMyVector(3); 将3 转换为CMyVector类型的临时变量。
std::cout << (d == 5) << std::endl; //这里的 5 也转换为 CMyVector(5), 故输出为 1
这里d = d + 3 实质上是将3隐式转换为CMyVector类型。
在d == 5 中 也是将 5隐式转换为CMyVector类型。
再探隐式转换
上面的我们看到 d = d + 3, 能够成功调用。 那 d = 3 + d 能行吗?
答案是否定的, 在我的VS2015编译器上,会提示:没有与这些操作符“+”相匹配的运行, 操作数类型为: int + CMyVector
编译时,会提示错误: 二进制“+”: 没有找到接受“CMyVector”类型的全局运算符(或没有可接受的转换)
想想,这是为什么呢??
首先我们看看:
CMyVector operator+ (const CMyVector & other);
很显然,在类成员函数 operator+ 中隐含了一个this 参数, 而这个this参数,必须是CMyVector类。
在 d = d + 3 中,调用的就是 d 的 operator+ 操作, 而参数 为 CMyVector类型, 恰好在CMyVector类的构造函数中, 存在将 int 型 转换为 CMyVector 类的 方法:
CMyVector(int ix = 0, int iy = 0, int iz = 0); //构造函数,这里注释掉 explicit, 表示允许隐式转换
而在 d = 3 + d 中,显然调用的 是 int 类型的 operator+ 操作,而这时在int类型 的 构造函数中, 不存在 将 CMyVector 转换为 int 类的 方法。 故编译器没法找到合适的函数去处理此操作。
这时,我们就想: 嗯。。。,那为什么编译器 不将 3 转化为 CMyVector(3) 类型呢?
答案是编译器没这么聪明啊, 想想我们定义的 operator+ 操作, 它隐含的第一个参数 是 this指针,而this指针的前提是 必须为CMyVector类。this指针是没法转化的啊,它是int型 就调用int型的 operater+操作, 是 CMyVector型就调用CMyVector型的operator+操作。 是先有的this 再分辨调用什么 operator+ 操作。
那么这时,我们想实现 d = 3 + d 怎么操作呢?
当然我能可以换个写法,进行明确的类型转化:
d = CMyVector(3) + d;
当然,更多的时候,我们会利用 友元操作符重载 技术,来完成这项工作。
何为友元?
友元函数 并不是类的成员函数,不拥有this指针,但是允许访问类的私有变量和函数。
在类成员中添加 友元操作符operator+ 函数:
friend CMyVector operator+ (const CMyVector & other1, const CMyVector & other2);
这样我们调用 d = 3 + d, 编译器就找到了调用方法, 将 3 转换为CMyVector类, 这里的 3 将相当于other1 , d 相当于other2。
最后看看输出:
构造函数 CMyVector: x = 1 y = 0 z = 0
构造函数 CMyVector: x = 2 y = 0 z = 0
赋值函数 operator=: x = 2 y = 0 z = 0
析构函数 ~CMyVector: x = 2 y = 0 z = 0
构造函数 CMyVector: x = 3 y = 0 z = 0
构造函数 CMyVector: x = 0 y = 0 z = 0
重载操作符 operator+: x = 5 y = 0 z = 0
拷贝构造函数 CMyVector: x = 5 y = 0 z = 0
析构函数 ~CMyVector: x = 5 y = 0 z = 0
赋值函数 operator=: x = 5 y = 0 z = 0
析构函数 ~CMyVector: x = 5 y = 0 z = 0
析构函数 ~CMyVector: x = 3 y = 0 z = 0
构造函数 CMyVector: x = 4 y = 0 z = 0
构造函数 CMyVector: x = 0 y = 0 z = 0
友元1 重载操作符 operator+: x = 4 y = 0 z = 0
拷贝构造函数 CMyVector: x = 9 y = 0 z = 0
析构函数 ~CMyVector: x = 9 y = 0 z = 0
赋值函数 operator=: x = 9 y = 0 z = 0
析构函数 ~CMyVector: x = 9 y = 0 z = 0
析构函数 ~CMyVector: x = 4 y = 0 z = 0
构造函数 CMyVector: x = 9 y = 0 z = 0
1
析构函数 ~CMyVector: x = 9 y = 0 z = 0
请按任意键继续. . .