1. 类型转换方式 : ① C 语言中的强制类型转换 , ② 使用转换操作符进行转换 ;
2. const_cast 转换操作符 : 主要用来修改类型的 const 与 volatile 属性 ;
3. const 属性转换 : 使用 const_cast 转换 const 属性 , 就是将常量类型转为变量类型 , 或者将变量类型转为常量类型 ;
4. const_cast 转换操作符代码示例 :
const char* str_const = "Hello";
char* str = const_cast<char*> (str_const);
//新式转换 :
//转换操作符 :
//const_cast : 主要用来修改类型的 const 与 volatile 属性 ,
// 将不可修改属性 const 转为 可修改的属性
// volatile 属性作用 : 保证获取一个变量值时 , 重新从内存读取该属性 ;
//将 const char* 类型变量 转为 char* 类型的变量
// 可以理解成将常量转为变量 , 这里也可以将变量转为常量
const char* str_const = "Hello";
char* str = const_cast<char*> (str_const);
此处将 const char* 类型变量 转为 char* 类型的变量 , 可以理解成将常量转为变量 , 这里也可以将变量转为常量 ;
1. static_cast 转换操作符 : 有以下作用 ;
2. 定义子类与父类 : 其中父类中定义两个函数 , 分别是普通函数和虚函数 , 子类重写这两个函数 ;
//定义父类 , 其中定义共有虚函数
// 虚函数主要是能根据实际类型调用对应方法
class Parent {
public:
void function() {
cout << " 父类方法 " << endl;
}
virtual void function_viurtual() {
cout << " 父类虚函数 " << endl;
}
};
//定义子类 , 共有继承父类 ,
// 将父类的方法和属性都转为 public
class Child : public Parent {
public :
void function() {
cout << " 子类方法 " << endl;
}
void function_viurtual() {
cout << " 子类虚函数 " << endl;
}
};
子类重写的普通函数与虚函数区别 :
- 普通函数 : 编译时确定调用子类的方法还是父类的方法 , 根据声明确定调用谁的方法 , 类型声明成子类 , 就调用子类的方法 , 类型声明成父类 , 就调用父类的方法 ;
- 虚函数 : 运行时确定调用的是子类的方法还是父类的方法 , 运行时调用哪个类的构造方法 , 该对象就是什么类型的 , 其调用对应类型的虚函数或虚函数实现 ;
3. 创建父类指针变量 :
Parent* parent = new Parent();
4. 将父类指针变量转为子类指针 :
Child* child = static_cast<Child*>(parent);
5. 分别调用子类和父类的普通函数 : 该函数调用父类还是子类的在编译时确定 ;
① " child->function() " 讨论 : 调用子类 Child 的 function 方法 , 这里的 function 方法时普通方法 , 其声明的是什么类型的变量 , 那么调用的就是哪个类的方法 , 该对象声明的是 Child 对象 , 那么调用的就是 子类的方法 ;
② " parent->function() " 讨论 : 调用父类 Parent 的 function 方法 , 同理 , parent 对象声明为 Parent 类型 , 那么其调用的方法就是父类的方法 ;
③ 代码示例 :
Parent* parent = new Parent();
Child* child = static_cast<Child*>(parent);
//调用子类 Child 的 function 方法
// 这里的 function 方法时普通方法 , 其声明的是什么类型的变量 ,
// 那么调用的就是哪个类的方法 , 该对象声明的是 Child 对象 ,
// 那么调用的就是 子类的方法
child->function();
//调用父类 Parent 的 function 方法
// 同理 , parent 对象声明为 Parent 类型 ,
// 那么其调用的方法就是父类的方法
parent->function();
子类方法
父类方法
6. 分别调用子类和父类的虚函数 : 虚函数方法调用子类还是父类的 , 是运行时决定的 , parent 对象使用 new Parent() 进行创建 , 那么无论何时 , 其虚函数都是调用父类的方法 ;
Parent* parent = new Parent();
Child* child = static_cast<Child*>(parent);
//这里测试调用子类和父类虚函数方法 ,
// 与上面的结果不同 , 虚函数方法调用子类还是父类的 , 是运行时决定的 ,
// parent 对象使用 new Parent() 进行创建 ,
// 那么无论何时 , 其虚函数都是调用父类的方法 ;
// 即使将其类型转为 Child 类型 , 其实际运行时的类型还是 Parent 类型
// 调用的虚函数方法始终是父类的方法 ;
parent->function_viurtual();
child->function_viurtual();
父类虚函数
父类虚函数
即使将其类型转为 Child 类型 , 其实际运行时的类型还是 Parent 类型 , 调用的虚函数方法始终是父类的方法 ;
1. dynamic_cast 转换操作符简介 :
安全检查内容 1 : 使用 dynamic_cast 转换操作符, 进行父类与子类强制转换时 , 父类必须有一个虚函数 , 否则代码编写的时候就会报错 ( 运行时 dynamic_cast 的操作数必须包含多态类型 ) ; 下图是删除父类的虚函数后 , IDE 开发环境提示出的错误 ;
2. 安全检查内容 2 : 类型不符合转换要求 ( 主要是将父类转为子类或子类转成父类 ) , 会转换失败 , 返回 null ;
3. dynamic_cast 转换操作符转换失败示例 :
//定义父类对象 , 然后将父类对象强转为子类对象
Parent* parent1 = new Parent();
Child* child1 = dynamic_cast<Child*>(parent1);
//根据转换结果打印不同的信息
if (!child1) {
//如果 child1 变量是 0 , 说明其转换结果为 null , !child1 结果大于 0
cout << " 父类 Parent 指针变量 转为 子类 Child 指针变量 转换失败 " << endl;
}
else {
//转换结果不为 null
child1->function_viurtual();
}
父类 Parent 指针变量 转为 子类 Child 指针变量 转换失败
4. 转换成功的情况 : 转换成功的前提是 , 子类可以转成父类 , 但是父类不能转换成子类 ; 开始时要创建子类对象 , 将其赋值给父类变量 , 之后还可以将该变量再次转为子类对象 , 反之则不可行 , 转换会失败 ;
//定义子类对象 , 然后将父类对象强转为子类对象
Parent* parent2 = new Child();
Child* child2 = dynamic_cast<Child*>(parent2);
//根据转换结果打印不同的信息
if (!child2) {
//如果 child1 变量是 0 , 说明其转换结果为 null , !child1 结果大于 0
cout << " 父类 Parent 指针变量 转为 子类 Child 指针变量 转换失败 " << endl;
}
else {
//转换结果不为 null
child2->function_viurtual();
}
子类虚函数
reinterpret_cast 转换操作符作用 : 对指针变量 , 引用变量进行原始的转换 , 即将地址值转成对应的类型 ;
// 4. reinterpret_cast 转换操作符
//作用 : 对指针变量 , 引用变量进行原始的转换 ;
char* hello = "Hello";
//获取 hello 字符串地址 , 将其转为 int 类型
int hello_address = reinterpret_cast<int> (&hello);
//打印 hello 的地址 , 并以 16 进制形式打印出来
cout << hex << &hello << endl;
//打印 hello_address , 并以 16 进制形式打印出来
cout << hex << hello_address << endl;
000000B6B62FE898
b62fe898
1. char* 转 int : 字符串变量转成整型变量 , 调用 C 函数 atoi(char*) 函数可以将字符串变量转成 int 类型变量 ;
2. char* 转 float : 字符串变量转成浮点型变量 , 调用 atof(char*) 函数可以将字符串变量转成 float 类型变量 ;
3. int 转 char* 变量 :
4. int 与 char* 转换代码示例 :
// 5. char* 与 int 进行转换
//将字符串转为 int 类型变量
int int_var = atoi("88888");
//将字符串转为浮点型变量
float float_var = atof("88.88f");
//打印转换结果 : 注意要输出 十进制数
cout << "int_var : " << dec << int_var << " float_var : " << float_var << endl;
//int 类型 转为字符串
char c[10];
itoa(888, c, 10);
//打印转换后的字符串
cout << c << endl;
char c1[10];
sprintf(c1, "%d", 8888);
//打印转换后的字符串
cout << c1 << endl;
int_var : 88888 float_var : 88.88
888
8888
1. 代码示例 :
//定义父类 , 其中定义共有虚函数
// 虚函数主要是能根据实际类型调用对应方法
class Parent {
public:
void function() {
cout << " 父类方法 " << endl;
}
virtual void function_viurtual() {
cout << " 父类虚函数 " << endl;
}
};
//定义子类 , 共有继承父类 ,
// 将父类的方法和属性都转为 public
class Child : public Parent {
public:
void function() {
cout << " 子类方法 " << endl;
}
void function_viurtual() {
cout << " 子类虚函数 " << endl;
}
};
// IX . 类型转换
//新式转换 :
// 1. const_cast 转换操作符 :
//const_cast : 主要用来修改类型的 const 与 volatile 属性 ,
// 将不可修改属性 const 转为 可修改的属性
// volatile 属性作用 : 保证获取一个变量值时 , 重新从内存读取该属性 ;
//将 const char* 类型变量 转为 char* 类型的变量
// 可以理解成将常量转为变量 , 这里也可以将变量转为常量
const char* str_const = "Hello";
char* str = const_cast<char*> (str_const);
// 2. static_cast 转换操作符
//定义父类对象 , 然后将父类对象强转为子类对象
Parent* parent = new Parent();
Child* child = static_cast<Child*>(parent);
//调用子类 Child 的 function 方法
// 这里的 function 方法时普通方法 , 其声明的是什么类型的变量 ,
// 那么调用的就是哪个类的方法 , 该对象声明的是 Child 对象 ,
// 那么调用的就是 子类的方法
child->function();
//调用父类 Parent 的 function 方法
// 同理 , parent 对象声明为 Parent 类型 ,
// 那么其调用的方法就是父类的方法
parent->function();
//这里测试调用子类和父类虚函数方法 ,
// 与上面的结果不同 , 虚函数方法调用子类还是父类的 , 是运行时决定的 ,
// parent 对象使用 new Parent() 进行创建 ,
// 那么无论何时 , 其虚函数都是调用父类的方法 ;
// 即使将其类型转为 Child 类型 , 其实际运行时的类型还是 Parent 类型
// 调用的虚函数方法始终是父类的方法 ;
parent->function_viurtual();
child->function_viurtual();
// 3. dynamic_cast 转换操作符
//定义父类对象 , 然后将父类对象强转为子类对象
Parent* parent1 = new Parent();
Child* child1 = dynamic_cast<Child*>(parent1);
//根据转换结果打印不同的信息
if (!child1) {
//如果 child1 变量是 0 , 说明其转换结果为 null , !child1 结果大于 0
cout << " 父类 Parent 指针变量 转为 子类 Child 指针变量 转换失败 " << endl;
}
else {
//转换结果不为 null
child1->function_viurtual();
}
//定义子类对象 , 然后将父类对象强转为子类对象
Parent* parent2 = new Child();
Child* child2 = dynamic_cast<Child*>(parent2);
//根据转换结果打印不同的信息
if (!child2) {
//如果 child1 变量是 0 , 说明其转换结果为 null , !child1 结果大于 0
cout << " 父类 Parent 指针变量 转为 子类 Child 指针变量 转换失败 " << endl;
}
else {
//转换结果不为 null
child2->function_viurtual();
}
// 4. reinterpret_cast 转换操作符
//作用 : 对指针变量 , 引用变量进行原始的转换 ;
char* hello = "Hello";
//获取 hello 字符串地址 , 将其转为 int 类型
int hello_address = reinterpret_cast<int> (&hello);
//打印 hello 的地址 , 并以 16 进制形式打印出来
cout << hex << &hello << endl;
//打印 hello_address , 并以 16 进制形式打印出来
cout << hex << hello_address << endl;
// 5. char* 与 int 进行转换
//将字符串转为 int 类型变量
int int_var = atoi("88888");
//将字符串转为浮点型变量
float float_var = atof("88.88f");
//打印转换结果 : 注意要输出 十进制数
cout << "int_var : " << dec << int_var << " float_var : " << float_var << endl;
//int 类型 转为字符串
char c[10];
itoa(888, c, 10);
//打印转换后的字符串
cout << c << endl;
char c1[10];
sprintf(c1, "%d", 8888);
//打印转换后的字符串
cout << c1 << endl;
2. 执行结果 :
子类方法
父类方法
父类虚函数
父类虚函数
父类 Parent 指针变量 转为 子类 Child 指针变量 转换失败
子类虚函数
00000033C8AFE698
c8afe698
int_var : 88888 float_var : 88.88
888
8888