C++强制类型转换

一、算数转换

        算术转换(Arithmetic conversions):在算术运算中,如果操作数为整数类型,会进行整数提升(Integral promotion),将较小的类型值提升为int类型(或者unsigned int,如果较小的类型是unsigned类型),然后进行运算;

int a = 5.2;
cout << a;//输出5
float b = 515.2;
long long c=1023546987412;
cout << a + b + c << endl;//输出的类型是longlong类型

二、强制转换

(转换的类型)数据

cout << 5 / 2 << endl;//输出2
cout << (double)5 / 2 << endl;//输出2.5
cout << (double)(5 / 2) << endl;//输出2

三、类的强制类型转换

  • 一个类可以有多个转换函数。
  • 多个参数的构造函数,除第一个参数外,如果其它参数都有缺省值,也可以作为转换函数。
  • Person(int)的隐式转换的场景:←
  1. 将 Person对象初始化为 int 值时。
  2. 将 int 值传递给接受Person参数的函数时。←
  3. 返回值被声明为 Person的函数试图返回 int 值时。
  • 在上述任意一种情况下,使用可转换为int,类型的内置类型时
#include<iostream>
using namespace std;
class Person {
public:
	int c_age;
	string c_name;
	float c_weight;
	Person(int age) :c_age(age),c_name("NULL"),c_weight(0) {
		cout << "调用了Person(int age)" << endl;
	}
	Person() :c_age(0), c_name("NULL"), c_weight(0) {
		cout << "调用了Person()" << endl;
	}
};

ostream& operator<<(ostream& cout, const Person& p){
	cout << "--->c_age:  " << p.c_age << endl;
	cout << "--->c_name:  " << p.c_name << endl;
	cout << "--->c_weight:  " << p.c_weight << endl;
	cout << endl << endl;
	return cout;
}

void show(const Person& p){
	cout << p;
}

Person say(){
	return 5;
}

int main() {
	Person p1(20);//常规写法
	cout << p1;

	Person p2 = 10;//隐式转换,将Person对象初始化为 int 值时。
	cout << p2;

	Person p3 = Person(15);//显式转换
	cout << p3;

	//将 int 值传递给接受Person参数的函数时。
	show(25);
	
	//返回值被声明为 Person的函数试图返回int值时。
	say();
	return 0;
}

        将构造函数用作自动类型转换函数似乎是一项不错的特性,但有时候会导致意外的类型转换。explicit 关键字用于关闭这种自动特性,但仍允许显示转换。“
        在实际开发中,如果强调的是构造,建议使用 explicit,如果强调的是类型转换,则不使用explici

explicit Person(int age);
Person p1=8;// 错误。
Person p2=Person(8); // 显示转换,可以。
Person p3=(Person)8; // 显示转换,可以。

四、static_cast

        static_cast的定义为:static_cast<type_name>(expression)
        type_name是转换的类型,expression是被转换的对象或者表达式。static_cast一般用于隐式转换,当type_name和express至少有一方可以隐式转换时,则可以用static进行强制类型转换。可以用于常见的int、float、double等类型转换;转换成功返回true,否则返回false(相当于C语言中的强制类型转换)。这样转换是不安全的,因为派生类的成员在基类中不一定存在。

#include<iostream>
#include <vector>
using namespace std;
class Person {
public:
	void func()const {
		cout << "hello i'm Person" << endl;
	}
};

class Child:public Person {
public:
	void func()const {
		cout << "hello i'm Child" << endl;
	}
};
int main() {
	//普通类型转换
	double a = 13.14;
	cout << a << endl;//输出13.14
	int b = static_cast<int>(a);
	cout << b << endl;//输出13

	//父类到子类的转化
	Person* p1 = new Person();
	p1->func();

	Child* p2 = static_cast<Child*>(p1);
	p2->func();
	return 0;
}

如果在派生类中添加一个成员age,因为在基类中没有成员age所以在使用static_cast转换的时候是不安全的会输出错误乱码

class Child:public Person {
public:
	int age = 20;
	void func()const {
		cout << "hello i'm Child. And i'm "<<age<<" years old!" << endl;
	}
};

五、dynamic_cast

        dynamic_cast的定义为:dynamic_cast<type_name>(expression)
        type_name是转换的类型,expression是被转换的对象或者表达式。dynamic一般用于基类指向派生类时的强制转换,转换成功返回true,失败返回false。它不像static_cast一样向下转换不安全,它是安全的。

        具体可以看这篇文章C++新特性08_强制转换dynamic_cast

六、const_cast

        定义为const_cast<type_name>(expression)
        type_name是转换的类型,expression是被转换的对象或者表达式。const_case有两个功能,分别是去掉const和加上const,一般用于去掉const,修改被const修饰为常量的值。但是修改的这个值本身不能是const常量,而是被二次引用或者传参数时被引用为const,才能修改,否则修改失败。同时type和express两个类型要一直去掉const,修改成功返回true,否则返回false。

int main() {
	int* a = new int(2);
	const int* serven_int_5 = const_cast<const int*>(a);     // 转换为常量指针
	*a = 3;
	*serven_int_5 = 4;              // 不能修改
	return 0;
}

七、reinterpret_cast

        reinterpret_cast的定义为:reinterpret_cast<type_name>(expression)

        type_name是转换的类型,expression是被转换的对象或者表达式。

        reinterpret_cast将double类型转换成int,再转换成double类型后精度不会丢失,而static_cast会丢失。

int main() {
	double a = 13.14;
	char* b = reinterpret_cast<char*>(&a);
	double* c = reinterpret_cast<double*>(b);
	cout << *c << endl;

	int* d = reinterpret_cast<int*>(&a);
	double* e = reinterpret_cast<double*>(d);
	cout << *e<< endl;
	return 0;
}

  • 13
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值