您的位置:首页 > 编程语言 > C语言/C++

C++学习笔记(十八)类型转换

2018-03-23 16:56 260 查看
#include <iostream>

using namespace std;

//static_cast      : 普通数据类型之间的强转
//reinterpret_cast : 指针数据类型之间的转换
//dynamic_cast     : 类层次之间数据类型的转换
//const_cast       : 去掉变量的常量属性


void func2(const char *s)
{
// s[0] = 'w';

// 在转化的过程中去掉 s 的 const 属性并将值赋值给 p
// 注意:转换完以后,s 的属性是不变的,原来s是什么属性,现在还是什么属性
char *p = const_cast<char *>(s);
p[0] = 'w';
// s[0] = 'w';  s 还是const属性
}

int main()
{
// str是一个字符数组
char str[] = "hello world";
func2(str);

cout << str << endl;

// str1 指向一个字符串常量
char *str1 = "hello world"
4000
;
func2(str1);
cout << str1 << endl;

// 字符串常量数组
char *str2[] = {"hello", "wrold"};
func2(str2[0]);
cout << str2 << endl;

return 0;
}
class Student
{

};

class Animal
{
public:
virtual void eat()
{
printf ("动物吃饭\n");
}
};

class Cat :public Animal
{
public:
virtual void eat()
{
printf ("猫吃饭\n");
}

void CatchMouse()
{
printf ("猫抓老鼠\n");
}
};

class Dog :public Animal
{
public:
virtual void eat()
{
printf ("狗吃饭\n");
}

void lookHome()
{
printf ("狗看家\n");
}
};

void func(Animal *pa)
{
pa->eat();

// 根据特殊的对象做一些特殊的事情

// dynamic_cast 将基类指针转换为派生类指针
// 1、如果这个基类指针指向确实是要转换的派生类类型的对象,返回指向这个对象的指针
// 2、如果这个基类指针指向的不是要转换的派生类类型的对象,返回的是空指针 NULL

// 猫:去抓老鼠
Cat *pc = dynamic_cast<Cat*>(pa);
if(pc != NULL)
pc->CatchMouse();

// 狗:去看家
Dog *pd = dynamic_cast<Dog *>(pa);
if (pd != NULL)
pd->lookHome();
}

int main3()
{
Animal a;
Cat c;
Dog d;
func(&a);
func(&c);
func(&d);

return 0;
}

int main2()
{
Cat *pc = new Cat;

// 基类指针指向派生类对象,这是语法允许的
// 一些允许隐式转换的地方,static_cast也可以用
Animal *pa = static_cast<Animal *>(pc);

// 不同类型的指针之间的转换只能用 reinterpret_cast 转换
// Student *ps = static_cast<Student*>(pc);

// reinterpret_cast 可以进行任意类型指针之间的转换
Student *ps = reinterpret_cast<Student*>(pc);

return 0;
}

int main1()
{
double d = 1.2;
int a = (int)d;
cout << a << endl;

int *pa = (int*)&d;
cout << *pa << endl;

// static_cast 用法:
(1)用于基本数据类型之间的转换,如把int转换为char,把int转换成enum,但这种转换的安全性需要开发者自己保证(这可以理解为保证数据的精度,即程序员能不能保证自己想要的程序安全),如在把int转换为char时,如果char没有足够的比特位来存放int的值(int>127或int<-127时),那么static_cast所做的只是简单的截断,及简单地把int的低8位复制到char的8位中,并直接抛弃高位。(2)把空指针转换成目标类型的空指针(3)把任何类型的表达式类型转换成void类型(4)用于类层次结构中父类和子类之间指针和引用的转换。对于以上第(4)点,存在两种形式的转换,即上行转换(子类到父类)和下行转换(父类到子类)。对于static_cast,上行转换时安全的,而下行转换时不安全的
int b = static_cast<int>(d); int b = static_cast<int>(d);
// int *pb = static_cast<int*>(&d);

// reinterpret_cast 用于指针之间的转换
int *pc = reinterpret_cast<int *>(&d);

// static_cast + reinterpret_cast 基本涵盖C语言的强制转换方式了
总结
C++中层次类型转换中无非两种:上行转换和下行转换对于上行转换,static_cast(编译时类型检查)和dynamic_cast(运行时类型检查)效果一样,都安全;对于下行转换:你必须确定要转换的数据确实是目标类型的数据,即需要注意要转换的父类类型指针是否真的指向子类对象,如果是,static_cast和dynamic_cast都能成功;如果不是static_cast能返回,但是不安全,可能会出现访问越界错误,而dynamic_cast在运行时类型检查过程中,判定该过程不能转换,返回NULL。

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: