1.c方式强制类型((type)
(a))转换存在的问题
(1)任意类型之间都可以进行转换,编译器很难判断其正确性
(2)在源码中无法快速定位所有使用强制类型转换的语句
c++中的强制类型转换,语法:xxx_cast<type>(a)
(1)static_cast
用于基本类型间的转换,不能用于基本类型指针间的转换,用于有继承关系类对象之间的转换和类指针之间的转换
(2)const_cast
用于去除变量的只读属性,强制转换的目标类型必须是指针或引用
(3)dynamic_cast
用于有继承关系的类指针间的转换,用于有交叉关系的类指针间的转换,具有类型检查的功能,需要虚函数的支持
通过子类指针去指向父类指针
#include <iostream>
using namespace std;
class base
{
public:
base()
{
cout << "base::base()" << endl;
}
virtual void func()
{
cout << "base::func()" << endl;
}
virtual ~base()
{
cout << "base::~base()" << endl;
}
};
class derived : public base
{
public:
virtual void func()
{
cout << "derived::func()" << endl;
}
};
int main()
{
base* p = new base; //初始化父类指针
derived* pd = dynamic_cast<derived*>(p); //由于父类指针指向的是父类,只有父类虚函数表,没有子类的虚函数表,所以转换失败
//如果使用static_cast或者reinterpret_cast,则能成功,调用pd->func则打印base::func()
//pd->func(); //由于pd=0,所以这里会程序崩溃
cout << "pd = " << pd << endl; //转换失败,打印 0
delete p;
p = reinterpret_cast<base*>(new derived); //等价于p = (base*)new derived; 或者 p = reinterpret_cast<base*>(new derived)
//或者static_cast
pd = dynamic_cast<derived*>(p); //由于父类指针指向的是子类,所以有子类虚函数表
pd->func(); //打印"derived::func()"
cout <<"pd = " << pd <<endl; //转换成功,打印地址值
delete p;
return 0;
}- 父类(无虚函数)强制转为子类时,可以用static_cast或者reinterpret_cast进行强转
(4)reinterpret_cast
用于指针类型间的转换,用于整数与指针类型间的强转
#include <stdio.h>
void staic_cast_demo() {
int i = 0x12345;
char c = 'c';
int* pi = &i;
char* pc = &c;
c = static_cast<char>(i);
// pc = static_cast<char*>(pi); //error,不能用于基本类型指针间的转换
}
void const_cast_demo() {
const int& j = 1; //只读变量
int& k = const_cast<int&>(j); //去除只读变量,可以通过k修改变量的值
const int x = 2; //常量,存在符号表里
int& y = const_cast<int&>(x); //内存会给这个常量分配一个临时的空间,并且y指向这块空间
// int z = const_cast<int>(x); //error,目标类型必须是指针或引用
k = 5;
printf("k=%d\n", k); //5
printf("j=%d\n", j); //5
y = 8;
printf("x=%d\n", x); //2
printf("y=%d\n", y); //8
printf("&x=%p\n", &x); //&x=0000006db754f964
printf("&y=%p\n", &y); //&y=0000006db754f964
}
void reinterpret_cast_demo() {
int i = 0;
char c = 'c';
int* pi = &i;
char* pc = &c;
pc = reinterpret_cast<char*>(pi);
pi = reinterpret_cast<int*>(pc);
pi = reinterpret_cast<int*>(i);
// c = reinterpret_cast<char>(i); //error,不能用于基本类型间的转换
}
void dynamic_cast_demo() {
int i = 0;
int* pi = &i;
// char* pc = dynamic_cast<char*>(pi); error,只能用于有继承关系的类指针间的转换
}
int main() {
staic_cast_demo();
const_cast_demo();
}2.const什么是只读变量,什么是常量?
(1)只有用字面量初始化的const常量才会进入符号表
const int x=1;
(2)使用其他变量初始化的const常量仍然是只读变量
const int& rx=x;
(3)被volatile修饰的const常量是易变的,因此不会进入符号表
即在编译期间不能直接确定初始值的const标识符,都被作为只读变量处理,只读变量仅仅意味着被const修饰的变量不能出现在赋值符号左边
#include <stdio.h>
int main() {
const int x = 1;
const int& rx = x;
int& nrx = const_cast<int&>(rx);
nrx = 5;
printf("x=%d\n", x);
printf("rx=%d\n", rx);
printf("nrx=%d\n", nrx);
printf("&x=%d\n", &x);
printf("&rx=%d\n", &rx);
printf("&nrx=%d\n", &nrx);
volatile const int y = 2; //加了volatile就是只读变量
int* p = const_cast<int*>(&y);
*p = 6;
printf("y=%d\n", y); //6
printf("p=%p\n", p); //p=000000d6682ff8d4
const int z = y;
p = const_cast<int*>(&z);
*p = 7;
printf("z=%d\n", z);
printf("p=%p\n", p);
char c = 'c';
char& rc = c;
const int& trc = c; //引用的类型不同,则会生成一个新的只读变量,即trc是只读变量
rc = 'a';
printf("c=%c\n", c);
printf("rc=%c\n", rc);
printf("trc=%c\n", trc);
}运行结果:

3.引用与指针的关系
指针:
(1)指针是一个变量,值为一个内存地址,不需要初始化,可以保存不同的地址
(2)通过指针可以访问对应内存地址中的值
(3)指针可以被const修饰为常量或只读变量
引用:
(1)引用只是变量的一个新名字,对引用的操作都会传递到代表的变量
(2)const引用使其代表的变量具有只读属性
(3)引用必须在定义时初始化,之后无法代表其他变量
#include <stdio.h>
int main() {
// const 常量
const int c = 0; //const局部变量
int* p = (int*)&c; //使用&操作符,会分配空间 int* p = (int*)&c -> const int& p = c;
*p = 5;
printf("c = %d,*p=%d\n", c, *p); // c = 0,*p=5 实际没有改变c自身的值。
// const 只读变量 (一般用在引用或者指针上)
int d = 1; // 临时变量,自身可读写
const int& p2 = d; // 其实这个p2 是个只读变量(可以通过const_cast去更改)
int& p3 = const_cast<int&>(p2);
p3 = 100;
printf("d = %d p2 = %d\n", d, p2); //d = 100 p2 = 100 实际目标d被改变了,因为d是个可读写的变量。
//所以引用修饰的const只是个标志,到底能不能更改目标,需要引用的目标类型是否是const
const int d2 = 1; // 引用的目标类型是const
const int& p4 = d2; // 其实这个p4 是个只读变量(可以通过const_cast去更改)
int& p5 = const_cast<int&>(p4);
p5 = 100;
printf("d2 = %d p4 = %d\n", d2, p4); //d = 100 p2 = 100 实际目标d2没有改变,因为d2是个常量。
return 0;
}到此这篇关于c++强制类型转化、const的理解的文章就介绍到这了,更多相关c++强制类型转化内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论