C++之类型转换

类型转换

一、类型的自动转换和强制转换

在C++中,存在隐式类型转语法(自动类型转换)
int a = 12;
a = 22.5 + a;

C++还提供了显式类型转换语法(强制类型转换)
类型名(变量)
int num = int(99.5);

C语言采用的语法格式
int num = (int)99.5;

注意:
1、不管是自定类型转换还是强制类型转换,前提是编译器必须知道如何转换,如:
①将浮点型数据赋值给整型变量时,舍弃小数部分。
②将整型数据赋值给浮点型变量时,数值不变,但是以指数形式储存。
③将double型数据赋值给float型变量时,注意数值范围溢出。
④字符型数据可以赋值给整型变量,此时存入的字符是ASCII码。
⑤将一个int,short或long型数据赋值给一个char型变量,只将低8位原封不动的送到char型变量中。
⑥将有符号型数据赋值给长度相同的无符号型变量,连同原来的符号位一起传送。


二、自定义类型之间的转换(基本类型转换为当前类型)

C++允许我们自定义类型转换规则
用户可以将其他类型转换为当前类类型,也可以将当前类类型转换为其他类型
这种自定义的类型转换规则只能以类的成员函数的形式出现
将其它类型转换为当前类型需要借助转换构造函数

//定义一个矩形
Rectangle();
Rectangle(float width);
Rectangle(float width,float height);
/********************************************/
Rectangle(22.5,18.8);
cout<< rect1 <<endl;
rect1 = 50.8//调用转换构造
cout<< rect1 <<endl;

注意:
1、为了获得目标类型,编译器会“不择手段”,会综合使用内置的转换规则和用户自定义的转换规则,并且会进行多级类型转换,例如:
Rectangle rect1(22.5,18.8);
Rectangle rect2;
rect2 = rect1 + 98;
编译器会根据内置规则先将int类型的98转换为double类型的98.0,再根据用户自定义规则将double类型的98.5转换为Rectangle类型。


三、自定义类型之间的转换具体实例

定义一个简单的Rectangle类输出宽和高。
Rectangle.h

#ifndef RECTANGLE_H
#define RECTANGLE_H
#include<iostream>

using namespace std;

//自定义的矩形类
class Rectangle
{
    public:
        Rectangle();                            //无参默认构造,可以由编译器自动生成
        Rectangle(float width, float height);   //带参构造
        Rectangle(const Rectangle & rect);      //拷贝构造
        Rectangle(float width);                 //转换构造 - 将其他类型转换为当期类型时使用
        virtual ~Rectangle();

        void display()
        {
            cout<<"width: "<<width<<",height:"<<height<<endl;
        }

    protected:

    private:
        float width;      //宽
        float height;     //高
};

#endif // RECTANGLE_H

Rectangle.cpp

#include "Rectangle.h"

Rectangle::Rectangle():width(0),height(0)
{
    //ctor
}
Rectangle::Rectangle(float width,float height):width(width),height(height)
{

}
Rectangle::Rectangle(const Rectangle & rect)
{

}
Rectangle::Rectangle(float width):width(width),height(width)
{
    //会绘制一个矩形
}

Rectangle::~Rectangle()
{
    //dtor
}

main.cpp

#include<iostream>
#include"Rectangle.h"

using namespace std;

void TestRectangle();

int main()
{
    TestRectangle();
    return 0;
}

void TestRectangle()
{
    Rectangle rect1;                //调用默认构造
    Rectangle rect2(25.0,50.5);     //调用带参构造
    Rectangle rect3(rect1);         //调用拷贝构造
    //能否与基本类型进行相互转换?
    Rectangle rect4 = 55;           //调用一个参数的构造 - 转换构造
    Rectangle rect5(66);

    rect2.display();
    rect4.display();
    rect5.display();
}


//打印结果:
/**
width: 25,height:50
width: 55,height:55
width: 66,height:66

*/

四、再谈构造函数

4.1、构造函数的作用
构造函数的本意是在创建对象的时候初始化对象。
编译器会根据传递的实参来匹配不同的(重载的)构造函数。

4.2、构造函数的分类
无参构造、带参构造、拷贝构造、转换构造。

//无参默认构造,可以由编译器自动生成
Rectangle();     
//带参构造,用户定义的普通带参构造                    
Rectangle(float width, float height);  
//拷贝构造,在以拷贝方式初始化对象时调用
Rectangle(const Rectangle & rect);    
//转换构造,将其他类型转换为当期类型时调用 
Rectangle(float width);      

//例:
Rectangle rect1;                //调用默认构造
Rectangle rect2(25.0,50.5);     //调用带参构造
Rectangle rect3(rect1);         //调用拷贝构造
Rectangle rect4 = 55;           //调用一个参数的构造 - 转换构造
Rectangle rect5(66);         	//调用转换构造
Rectangle rect6 = 'A' + rect5 + false;	//自动调用转换

是将char和bool都转换成Rectangle类型再进行运算。

4.3、将几个构造融合在一起的写法:

//Rectangle.h
//融合了无参构造,带参构造,转换构造
Rectangle(float width = 0, float height = 0):width(width),height(height){}

4.4、构造函数详细内容可以查看博客:构造函数


五、当前类型转换为其他类型(转为基本类型或者其它类型)

5.1、类型转换函数
类型转换函数的作用就是将当前类型,类型转换为其它类型。
它只能以成员函数的形式出现,也就是只能出现在类中。

5.2、类型转换函数的语法格式

//类型转换函数的语法格式
operator type(){
	return data;
}

5.3、类型转换函数的特点
1、类型转换函数看起来没有返回值类型,其实是隐式地指明了返回值类型。
2、类型转换函数也没有参数,因为要将当前类的对象转换为其它类型。

实际上编译器会把当前对象的地址赋值给this指针,这样在函数体内就可以操作当前对象了

//例:
operator float() const{
	return this->width;
}

operator Circle(){
	return Circle(width * 2);
}

六、当前类型转换为其他类型实例

需求:Rectangle和Circle之间可以自由转换

Rectangle.h

#ifndef RECTANGLE_H
#define RECTANGLE_H
#include<iostream>
#include "Circle.h"

using namespace std;

//自定义的矩形类
class Rectangle
{
    public:
       // Rectangle();                            //无参默认构造,可以由编译器自动生成
        //Rectangle(float width, float height);   //带参构造
        Rectangle(const Rectangle & rect);      //拷贝构造
        //Rectangle(float width);                 //转换构造 - 将其他类型转换为当期类型时使用
        virtual ~Rectangle();

        //将几个构造融合在一起的写法
        Rectangle(float width = 0, float height = 0):width(width),height(height){}

        operator float() const{ //将矩形转换成float型
            return width;
        }

        operator Circle() const{ //将矩形转换为Circle型
            return Circle(width / 2);
        }

        void display()
        {
            cout<<"width: "<<width<<",height:"<<height<<endl;
        }

    protected:

    private:
        float width;      //宽
        float height;     //高
};

#endif // RECTANGLE_H

Rectangle.cpp

#include "Rectangle.h"

/*Rectangle::Rectangle():width(0),height(0)
{
    //ctor
}
Rectangle::Rectangle(float width,float height):width(width),height(height)
{

}*/
Rectangle::Rectangle(const Rectangle & rect)
{

}
/*
Rectangle::Rectangle(float width):width(width),height(width)
{
    //会绘制一个矩形
}*/

Rectangle::~Rectangle()
{
    //dtor
}

Circle.h

#ifndef CIRCLE_H
#define CIRCLE_H
#include<iostream>
using namespace std;

class Circle
{
    public:
       // Circle();
        Circle(float radius = 0):radius(radius){}
        virtual ~Circle();

        friend ostream & operator<<(ostream & out ,const Circle & circle);

    protected:

    private:
        float radius;       //半径
        float area;         //面积
};


#endif // CIRCLE_H

Circle.cpp

#include "Circle.h"

/*Circle::Circle()
{
    //ctor
}*/

Circle::~Circle()
{
    //dtor
}
ostream & operator<<(ostream & out ,const Circle & circle)
{
    out<<circle.radius;
    out<<endl;
    return out;
}

main.cpp

#include<iostream>
#include"Rectangle.h"
#include "Circle.h"

using namespace std;

void TestRectangle();

int main()
{
    TestRectangle();
    return 0;
}

void TestRectangle()
{
    Rectangle rect1;                //调用默认构造
    Rectangle rect2(25.0,50.5);     //调用带参构造
    Rectangle rect3(rect1);         //调用拷贝构造
    //能否与基本类型进行相互转换?
    Rectangle rect4 = 55;           //调用一个参数的构造 - 转换构造
    Rectangle rect5(66);

    rect4.display();

    float rect4_width = float(rect4);
    cout<<"rect4_width = "<<rect4<<endl;

    Circle circle1 = rect4;          //Rectangle和Circle之间可以自由转换
    cout<<"圆的信息:"<<circle1<<endl;

}

//打印结果:
/**
width: 55,height:0
rect4_width = 55
圆的信息:27.5


*/

注意:
1、type可以是内置类型,类类型以及由typedef定义的类型别名,任何作为函数返回类型的类型(void除外)都是支持的(不允许转换为数组或函数类型,可以转换为指针或者引用类型)。
2、类型转换函数一般不会更改被转换的对象,所以通常被定义为const。
3、类型转换函数可以被继承,可以是虚函数。


七、小结

自定义类型转换有四种:
默认构造函数、带参构造函数、复制(拷贝)构造函数和转换构造函数。

当前类型转换为基本类型或者其它类型可以使用类型转换函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值