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;
}
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;
}
相关文章推荐
- C++学习笔记(类型转换)
- C++学习笔记(十一):void*指针、类型转换和动态内存分配
- 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_c
- 常用数据类型使用转换详解
- redis-Mybatis二级缓存报类型转换错误
- C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
- Date、String、Calendar类型之间的转换
- 关于数据类型转换
- _itoa atoi、atof、itoa、itow _itoa_s 类型转换使用说明
- Visual C++常用数据类型转换详解
- C 数据类型转换
- PostgreSQL 类型转换
- PHP笔记2__变量/字符串/类型转换/常量/,,
- C# 泛型 无法将类型xx隐式转换为“T”
- 对VC中有关数据类型转换的整理
- 隐式类类型转换
- Linq数据类型转换
- C/C++中int/long/float/double数值类型与字符串互相转换
- 1.4 类型转换和条件运算
- Struts2类型转换----常规类型,自定义类型,错误处理