C++ 类型隐式转换学习

来源:互联网 发布:淘宝内容营销是什么 编辑:程序博客网 时间:2024/05/21 19:07

何为隐式转换?

   我的理解是:编译器自动调用某类的构造函数,将其他类转换为此类,以方便明确某些操作。这样说起来比较难理解,直接以例子说明。

  先定义一个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 = 01析构函数 ~CMyVector: x = 9       y = 0   z = 0请按任意键继续. . .