7、C++的类型转换

#include <iostream>
using namespace std;

/*
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b = (TYPE)a
C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。
  static_cast		静态类型转换。如int转换成char
  reinterpreter_cast	重新解释类型
  dynamic_cast		命名上理解是动态类型转换。如子类和父类之间的多态类型转换。
  const_cast,		字面上理解就是去const属性。
  4种类型转换的格式:
  TYPE B = static_cast<TYPE> (a)
  */

void main01()
{
	double pi = 3.1415926;
	//C风格的强制类型转换(Type Cast)很简单
	//TYPE b = (TYPE)a;
	int num1 = (int)pi;

	//C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。
	//static_cast		静态类型转换。如int转换成char
	//reinterpreter_cast	重新解释类型
	//dynamic_cast		命名上理解是动态类型转换。如子类和父类之间的多态类型转换。
	//const_cast,		字面上理解就是去const属性。
	//4种类型转换的格式:
	//TYPE B = static_cast<TYPE> (a)
	int num2 = static_cast<int> (pi);//静态类型转换  编译的时c++编译器会做类型检查
	int num3 = pi; //c语言中 隐式类型转换的地方 均可使用 static_cast<>() 进行类型转换

	//char* ===> int *
	//1)static_cast<>()	静态类型转换,编译的时c++编译器会做类型检查;
	//基本类型能转换但是不能转换指针类型
	char *p1 = "hello...itcast ";
	int *p2 = NULL;
	//p2 = static_cast<int *>(p1);// 使用static_cast, 编译器编译时,会做类型检查 若有错误 提示错误

	//2)若不同类型之间,进行强制类型转换,用reinterpret_cast<>()进行重新解释
	//3)一般性结论:
	//C语言中能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;
	//C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型解释。总结:static_cast<>()和reinterpret_cast<>()基本上把C语言中的强制类型转换给覆盖
	//reinterpret_cast<>()很难保证移植性

	p2 = reinterpret_cast<int *>(p1); //若不同类型之间,进行强制类型转换,用reinterpret_cast<>() 进行重新解释

	cout << "p1:" << p1 << endl; //%s
	cout << "p2" << p2 << endl; //%d
	//总结:通过 reinterpret_cast<>() 和 static_cast<>()把C语言的强制类型转换 都覆盖了..
	cout << "hello..." << endl;
	system("pause");
	return;
}

7.1 类型转换名称和语法

C风格的强制类型转换(TypeCast)很简单,不管什么类型的转换统统是:

TYPE b =(TYPE)a

C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。

    static_cast                静态类型转换。如int转换成char

                   reinterpreter_cast  重新解释类型

           dynamic_cast           命名上理解是动态类型转换。如子类和父类之间的多态类型转换。

const_cast,            字面上理解就是去const属性。

4种类型转换的格式:

         TYPE B = static_cast<TYPE>(a)

7.2 类型转换一般性介绍

         1)static_cast<>()  静态类型转换,编译的时c++编译器会做类型检查

基本类型能转换但是不能转换指针类型

         2)若不同类型之间,进行强制类型转换,用reinterpret_cast<>()进行重新解释

         3)一般性结论:

C语言中能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;

C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型解释。总结:static_cast<>()和reinterpret_cast<>()基本上把C语言中的强制类型转换给覆盖

reinterpret_cast<>()很难保证移植性。

         4)dynamic_cast<>(),动态类型转换,安全的基类和子类之间转换;运行时类型检查

         5)const_cast<>(),去除变量的只读属性        

#include <iostream>
using namespace std;

/*
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b = (TYPE)a
C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。
  static_cast		静态类型转换。如int转换成char
  reinterpreter_cast	重新解释类型
  dynamic_cast		命名上理解是动态类型转换。如子类和父类之间的多态类型转换
  const_cast,		字面上理解就是去const属性。
  4种类型转换的格式:
  TYPE B = static_cast<TYPE> (a)
  */
//dynamic_cast		命名上理解是动态类型转换。如子类和父类之间的多态类型转换
//抽象类
class Animal
{
public:
	virtual void cry() = 0;//纯虚函数
private:

};

class Dog :public Animal
{
public:
	virtual void cry()
	{
		cout << "旺旺" << endl;
	}

	void doHome()
	{
		cout << "看家" << endl;
	}

};

class Cat :public Animal
{
public:
	virtual void cry()
	{
		cout << "喵喵" << endl;
	}

	void doThing()
	{
		cout << "抓老鼠" << endl;
	}

};
//发生多态条件
//1.要有继承 2.要有虚函数重写 3.要有父类指针指向子类对象
void playObj(Animal *base)
{
	base->cry();
	//能识别子类对象
	// dynamic_cast 运行时类型识别  RIIT
	Dog *pDog = dynamic_cast<Dog *>(base);
	if (pDog != NULL)
	{
		pDog->doHome();//让狗 做自己特有的事情
	}

	Cat *pCat = dynamic_cast<Cat *>(base);
	if (pCat != NULL)
	{
		pCat->doThing();//让猫 做自己特有的事情
	}

}

class Tree
{
public:


private:

};


void main()
{
	Dog d1;
	Cat c1;

	playObj(&d1);
	playObj(&c1);

	Animal *pBase = NULL;

	pBase = &d1;

	pBase = static_cast<Animal *>(&d1); //让C++编译在编译的时候进行 类型检查 

	//强制类型转换 
	pBase = reinterpret_cast<Animal *>(&d1);

	{
		Tree t1;
		//pBase = static_cast<Animal *>(&t1); // C++编译器会做类型检查
		pBase = reinterpret_cast<Animal *>(&t1);  //reinterpret_cast 重新解释 ....强制类转换的味道
	}
	system("pause");
	cout << "hello..." << endl;
	system("pause");
	return;
}
#include <iostream>
using namespace std;

/*
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b = (TYPE)a
C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。
  static_cast		静态类型转换。如int转换成char
  reinterpreter_cast	重新解释类型
  dynamic_cast		命名上理解是动态类型转换。如子类和父类之间的多态类型转换
  const_cast,		字面上理解就是去const属性。
  4种类型转换的格式:
  TYPE B = static_cast<TYPE> (a)
  */

//const char *p 的const修饰 让p指向的内存空间 变成只读属性
//const char * p 和 char const * p 是一个意思,都是p所指向的变量的值不能改变
//char* const p,意思是p所指向的地址是不能改变的
void printBuf(const char *  p)
{
	//p[0] = 'Z';
	char *p1 = NULL;
	//程序员 要清楚的知道 变量:转换之前是什么类型 ,转换之后是什么类型
	//const char * ===> char * //把只读属性 去掉
	p1 = const_cast<char *>(p);

	p1[0] = 'Z';  //通过p1 去修改了内存空间
	cout << p << endl;
}

void main()
{
	char buf[] = "aaaaaaaaafffffddd";

	char *myp = "aaaaaaaaafffffddd";

	//程序员 要确保 p所指向的内存空间 确实能修改 ;如果不能修改会带来灾难性后果
	//printBuf (buf);

	printBuf(myp);

	system("pause");
	cout << "hello..." << endl;
	system("pause");
	return;
}

7.3 典型案例

7.3.1 static_cast用法和reinterpret_cast用法

void main01()

{

         double dPi = 3.1415926;

         //1静态的类型转换:  在编译的时进行基本类型的转换能替代c风格的类型转换可以进行一部分检查

         int num1 = static_cast<int> (dPi); //c++的新式的类型转换运算符

         int num2 = (int)dPi;                              //c语言的旧式类型转换

         int num3 = dPi;                                                        //隐士类型转换

         cout << "num1:" << num1 << " num2:" << num2 << " num3:" << num3 << endl;

         char *p1 = "hello wangbaoming " ;

         int *p2 = NULL;

         p2 = (int *)p1;

         //2 基本类型能转换但是不能转换指针类型

         //p2 = static_cast<int *> (p1); //“static_cast”: 无法从“char *”转换为“int *”

         //3 可以使用  reinterpret_cast 进行重新解释

         p2 = reinterpret_cast<int *> (p1);

         cout << "p1 " << p1 << endl;

         cout << "p2 " << p2 << endl;

         //4 一般性的结论:      c语言中能隐式类型转换的在c++中可以用 static_cast<>()进行类型转换  //C++编译器在编译检查一般都能通过

         //c语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型解释

        

         system("pause");

         return ;

}

7.3.2 dynamic_cast用法和reinterpret_cast用法

class Animal

{

public:

         virtual void  cry() = 0;

};

class Dog : public Animal

{

public:

         virtual void  cry()

         {

                   cout << "wangwang " << endl;

         }

         void doSwim() 

         {

                   cout << "我要狗爬" << endl;

         }

};

class Cat : public Animal

{

public:

         virtual void  cry()

         {

                   cout << "miaomiao " << endl;

         }

         void doTree() 

         {

                   cout << "我要爬树" << endl;

         }

};

class Book

{

public:

         void printP()

         {

                   cout << price << endl;

         }

private:

         int price;

};

void ObjPlay(Animal *base)

{

         base->cry();

         Dog *pDog = dynamic_cast<Dog *>(base);

         if (pDog != NULL)

         {

                   pDog->cry();

                   pDog->doSwim();

         }

         Cat *pCat = dynamic_cast<Cat *>(base);

         if (pCat != NULL)

         {

                   pCat->cry();

                   pCat->doTree();

         }

}

void main02()

{

         Animal *base = NULL;

         //1 可以把子类指针赋给父类指针但是反过来是不可以的需要如下转换

         //pdog = base; 

         Dog *pDog = static_cast<Dog *> (base);

         //2 把base转换成其他非动物相关的 err

         //Book *book= static_cast<Book *> (base);

         //3  reinterpret_cast //可以强制类型转换

         Book *book2= reinterpret_cast<Book *> (base);

         //4 dynamic_cast用法

         ObjPlay(new Cat());

         system("pause");

}

7.3.3const_cast用法

//典型用法把形参的只读属性去掉

void Opbuf(const char *p)

{

         cout << p << endl;

         char *p2 = const_cast<char*>(p);

         p2[0] = 'b';

         cout << p << endl;

}

void main()

{

         const char *p1 = "11111111111";

         char *p2 = "22222222";

         char *p3 = const_cast<char *>(p1);

         char buf[100] = "aaaaaaaaaaaa";

         Opbuf(buf);

         //要保证指针所执行的内存空间能修改才行若不能修改还是会引起程序异常

         //Opbuf("dddddddddddsssssssssssssss");

         system("pause");

}

7.4 总结

结论1:程序员要清除的知道: 要转的变量,类型转换前是什么类型,类型转换后是什么类型。转换后有什么后果。

结论2:一般情况下,不建议进行类型转换;避免进行类型转换。


猜你喜欢

转载自blog.csdn.net/weixin_40807247/article/details/81055065