文章目录
一、内置类型与内置类型
1、隐式类型转换:一般是类型与类型之间关联性大的才能进行转换,如:整形与整形、整形与浮点型。
 2、显示类型转换:当有关联但是不大时,不能进行隐式类型转换时,就需要进行显示类型转换了,如:指针与整形,不同类型的指针之间。
 3、演示:
//隐式类型转化:整形与整形 整形与浮点型
//显示类型转化:指针与整形 不同指针之间指针
void test01()
{
	int a = 10;
	double b = 1.1;
	char c = 'a';
	
	
	//整形与整形
	a = c;
	//整形与浮点型
	a = b;
	int* p2 = &a;
	//int d = p;	err
	int d = (int)p1;
	//指针与指针
	//char* cp = p; err
	char* cp = (char*)p1;
}
 
二、内置类型与自定义类型
1、内置类型转换为自定类型:这个能不能转换是通过自定义类型的构造函数决定的。
 2、自定义类型转换为内置类型:需要自定义类型进行重载,(不需要写返回类型)operator type(转化的内置类型) () 。
 3、演示:
class Base1
{
public:
	Base1(int a = 10,int b = 10):_a(a),_b(b)
	{}
	//用与转化的函数
	operator int()
	{
		return _a + _b;;
	}
	void Printf()
	{
		cout << "_a:" << _a << "_b:" << _b << endl;
	}
private:
	int _a = 10;
	int _b = 10;
};
void test02()
{
	//内置类型转化为自定义类型
	Base1 b = { 1,1 };
	//Base1 b = Base1(1,1);
	b.Printf();
	
	//自定义类型转化为内置类型
	int a = Base1();
	//int a = b.operator int();
	cout << a << endl;
}
 
三、内置类型与内置类型
1、自定义类型与自定义类型之间转化:看相互的构造函数,如:普通迭代器转换为const迭代器。
 2、演示:
//声明Base3
class Base3;
class Base2
{
	// Base3作为Base2的友元
	friend class Base3;
public:
	Base2(int a = 1, int b = 1) :_a(a), _b(b)
	{}
	void Printf()
	{
		cout << "_a:" << _a << "_b:" << _b << endl;
	}
private:
	int _a ;
	int _b ;
};
class Base3
{
public:
	
	Base3(int c = 2, int d = 2) :_c(c), _d(d)
	{}
	//实现用Base2构造Base3的构造函数
	Base3(const Base2& b2) :_c(b2._a), _d(b2._b)
	{}
	void Printf()
	{
		cout << "_c:" << _c << "_d:" << _d << endl;
	}
private:
	int _c ;
	int _d ;
};
void test03()
{
	//使用Base2转化为Base3
	Base3 b3 = Base2();
	//Base3 b3(Base2());	Base2用匿名对象构造Base3
	b3.Printf();
}
 
四、c++标准中的4种类型类型转换
1、c++为什么要有这4种转换
2、 static_cast
(1)介绍
(2)语法格式
T a = static_cast<T(需要转换到的类型)> (b)	//由b类型转到a类型
 
(3)使用
//基本数据类型之间的转换
double pi = 3.14159;  
int ip = static_cast<int>(pi); // 将 double 类型的 pi 转换为 int 类型的 ip,并截断小数部分
// 类的向上转换(派生类到基类)
class Base {};  
class Derived : public Base {};  
Derived d;  
Base* b = static_cast<Base*>(&d); // 将 Derived 类型的指针转换为 Base 类型的指针
//类的向下转换(基类到派生类) ,注意:这种类型转换是不安全的
Base* b = new Derived();  
Derived* d = static_cast<Derived*>(b); // 将 Base 类型的指针转换为 Derived 类型的指针
 
3、reinterpret_cast
(1)介绍
(2)语法
 与 static_cast语法格式一样。
(3)使用
//指针类型之间的转换
int* ptr1 = new int(10);  
char* ptr2 = reinterpret_cast<char*>(ptr1); // 将 int* 转换为 char*
//指针与整数类型之间的转换
int* ptr = new int(42);  
char* addr = reinterpret_cast<uintptr_t>(ptr); // 将 int* 转换为 char* 
 
4、 const_cast
(1)介绍
(2)什么是易变性?
(3)语法格式
 与 static_cast语法格式一样。
(4)使用
 移除常量性(常用)
const int a = 10;  
int* ptr = const_cast<int*>(&a); // 移除 a 的常量性  
*ptr = 20; // 未定义行为,因为 a 实际上是常量
 
注意:上面的例子展示了 const_cast 的用法,但尝试修改 a 的值是未定义行为,因为 a 是在栈上声明的常量,下面使用才是合理的:
const int* ptrToConst = &someNonConstInt; // someNonConstInt 是 int 类型的非 const 对象  
int* ptrToNonConst = const_cast<int*>(ptrToConst);  
*ptrToNonConst = 42; // 现在可以安全地修改对象
 
5、 dynamic_cast
(1)介绍
(2)语法格式
 与 static_cast语法格式一样。
(3)使用
 向下转型
class Base {  
public:  
    virtual ~Base() {} // 需要虚析构函数  
};  
  
class Derived : public Base {  
};  
  
Base* basePtr = new Derived();  
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 转换成功  
if (derivedPtr != nullptr) {  
    // ... 使用 derivedPtr  
}  
  
delete basePtr;
 
向上转型
class Base {  
public:  
    virtual ~Base() {} // 需要虚析构函数  
};  
  
class Derived : public Base {  
};  
  
Derived* derivedPtr = new Derived();  
Base* basePtr = dynamic_cast<Base*>(derivedPtr); // 转换成功  
delete derivedPtr;
 
(4)注意:










