C++之类类型转换

C++存在类类型,必然也存在类的类型转换,和标准类型一样,两个类型必须有相似性,才可以相互转换。比如不能把一个string类型转换成double类型,就算强制转换也是不可以滴,类的转换方式有两种:类型转换的构造器和类型转换操作符函数。

一、类型转换构造器
还是先给个例子:

class Point2D{
private:
    int _x;
    int _y;
public:
    Point2D(int x = 0, int y = 0):_x(x), _y(y){}
    friend class Point3D;
    friend ostream& operator<<(ostream& os, Point2D &p2){
        os << "( " << p2._x << "," << p2._y << " )";
        return os;
    }
};

class Point3D{
private:
    int _x;
    int _y;
    int _z;
public:
    Point3D(int x = 0, int y = 0, int z = 0):_x(x), _y(y), _z(z){}
    Point3D(const Point2D &p2){    //类型转换构造器
        this->_x = p2._x;
        this->_y = p2._y;
        this->_z = 0;
    }
    friend ostream& operator<<(ostream& os, Point3D &p3){
        os << "( " << p3._x << "," << p3._y << "," << p3._z << " )";
        return os;
    }
};

int main()
{
    Point2D p2(1,2);
    Point3D p3 = p2;
    cout << p2 << endl;
    cout << p3 << endl;
    return 0;
}

结果为:
这里写图片描述

显然从Point2D类型成功转换到了Point3D类型。

从例子可以看出,这个类型转换函数其实就是个构造器,并且只有一个参数,这有这样的才称为类型转换构造器,多个参数或没有参数的都只是构造器而已。这里给出类型转换构造器的格式:

目标类{
	目标类(const 源类 & 类名){
		源类转换成目标类的函数体语句
	}
};

可以看出来,这个类型转换构造器是放在目标类里面的,同时不要忘了因为目标类可能要访问源类的私有成员,那就得把目标类声明为源类的友元类,当然也可以只把类型转换构造器声明为源类的友元函数,就是格式比较麻烦,说友元时(C++之友元)已经详细说明了,这里就不重复解释了。

二、类型转换操作符函数

还是先举个例子,上面是把Point2D转换成Point3D,这次把Point3D转换成Point2D:

class Point2D{
private:
    int _x;
    int _y;
public:
    Point2D(int x = 0, int y = 0):_x(x), _y(y){}
    friend ostream& operator<<(ostream& os, Point2D &p2){
        os << "( " << p2._x << "," << p2._y << " )";
        return os;
    }
};

class Point3D{
private:
    int _x;
    int _y;
    int _z;
public:
    Point3D(int x = 0, int y = 0, int z = 0):_x(x), _y(y), _z(z){}
    friend ostream& operator<<(ostream& os, Point3D &p3){
        os << "( " << p3._x << "," << p3._y << "," << p3._z << " )";
        return os;
    }
    operator Point2D(void){    //类型转换操作符函数
        return Point2D(this->_x, this->_y);
    }
};

int main()
{
    Point3D p3(1,2,3);
    Point2D p2 = p3;
    cout << p3 << endl;
    cout << p2 << endl;
    return 0;
}

执行结果:
这里写图片描述

从例子可以看出源类转换到目标类,是在源类中声明类型转换操作符函数,并且,无参无返回,却有return(不要问为什么,甲鱼臀部的规定,你懂得),下面给出类型转换操作符函数的格式:

源类{
operator 目标类(void){
		源类转换目标类的函数体语句
	}
};

三、explicit

explicit 是个仅用于声明的关键字,表示必须使用显示方式进行类型转换,否则就报错:

explicit Point3D(const Point2D &p2){
    this->_x = p2._x;
    this->_y = p2._y;
    this->_z = 0;
}

explicit operator Point2D(void){
  return Point2D(this->_x, this->_y);
}

现在把类型转换构造器和类型转换操作符函数前面都加了一个explicit的关键字,那么在做类型转换时:

	Point2D p2(1,2);
    Point3D p3 = p2;    //编译报错
    cout << p2 << endl;
    cout << p3 << endl;
    Point3D p31(1,2,3);
    Point2D p21 = p31;    //编译报错
    cout << p31 << endl;
    cout << p21 << endl;

现在就不可以使用隐式转换,就需要改成:

	Point3D p3 = (Point3D)p2;
    Point2D p21 = (Point2D)p31;
    //或者
    Point3D p3 = static_cast<Point3D>(p2);
    Point2D p21 = static_cast<Point2D>(p31);

这两种格式都可以,关键就要做出显示类型转换,当然如果不声明explicit,类型转换默认都是可以进行隐式类型转换的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值