c++-cast

145 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天点击查看活动详情

上行转换 下行转换

上行转换:把派生类的指针或引用转换成基类表示 下行转换:把基类的指针或引用转换成派生类表示

typeid(获取对象类型和类型对比)

typeid 只能获取对象的实际类型,即便这个类含有虚函数,也只能判断当前对象是基类还是派生类,而不能判断当前指针是基类还是派生类

	int a = 0;
	cout << typeid(a).name();//int

class father
{public:
	virtual void fun()
	{

	}
};
class son :public father
{
public:
	virtual void fun()
	{

	}
};
void main()
{
	father *a = new son;
	cout << typeid(*a).name();//class son
	if (typeid(*a) == typeid(son))
	{
		cout << "一样!" << endl;
	}
}

在这里插入图片描述

dynamic_cast

将一个指向基类的指针转换成指向派生类的指针;如果失败,返回空指针。 能够在类层次中进行向上转换 这个是将基类指针转换为子类指针 但是基类一定要有虚函数 要不然会报错

class Base
{
public:
	virtual void f() { cout << "Base's f()" << endl; }
};

// 我是子类
class Son : public Base
{
public:
	void f() { cout << "Son's f()" << endl; }

	int data; // 我是子类独有成员
};
Base *base; 

Son *son;
base = dynamic_cast<Base*>(son);

相较于基类指针直接指向子类对象 Base* base = new Son;应该会更安全

不用多申请地址

当我们想实现一个函数可以多个子类使用时 并且子类中有父类没有的函数 一般是

class Father
{public:
	virtual void fun()
	{
		cout << "i am father" << endl;
	}
};
class Son :public Father
{
public:
	virtual void fun()
	{
		cout << "i am son" << endl;
	}
	void fun2()//父类没有的方法
	{
		cout << "son fun2" << endl;
	}
};
void doThing(Father *a)
{
	if (typeid(*a) == typeid(Son))
	{
		Son *son = new Son;//需要重新创建一个对象
		son->fun2();
		delete(son); 
	}
	if (typeid(*a) == typeid(Father))
	{
		a->fun();
	}
}
void main()
{
	Father father;
	Son son;
	cout << a << endl;
	cout << son << endl;
	doThing(&son);
}

在这里插入图片描述

而dynamic_cast是

class Father
{public:
	virtual void fun()
	{
		cout << "i am father" << endl;
	}
};
class Son :public Father
{
public:
	virtual void fun()
	{
		cout << "i am son" << endl;
	}
	void fun2()//父类没有的方法
	{
		cout << "son fun2" << endl;
	}
};
void doThing(Father *a)
{
	if (typeid(*a) == typeid(Son))
	{
		Son* son = dynamic_cast<Son*>(a);
		cout << a << endl;
		cout << son << endl;
		son->fun2();
	}
	if (typeid(*a) == typeid(Father))
	{
		Father* father = dynamic_cast<Father*>(a);
		father->fun();
	}
}
void main()
{
	Father father;
	Son son;
	doThing(&son);
}

在这里插入图片描述

static_cast

实现C++种内置基本数据类型之间的相互转换,不能用于两个不相关类型进行转换。 static_cast在编译时会进行类型检查,而强制转换不会。

int a = 8;
int b = 3;
double result = static_cast<double>(a) / static_cast<double>(b);

将a和b从int转为double

const_cast

结合static_cast,可以在非const版本的成员函数内添加const,调用完const版本的成员函数后,再使用const_cast去除const限定。

作用

通过指针改变const类型对象的数据

下面这样明显是不被允许的

	const int a = 8;
	int* b= &a;
	*b = 7;
	/*引用也不行*/
	//const int A= 8;
	//int& B = A;

只能改成如下形式

const int a= 8;
	const int* b= &a;
	int* c= const_cast<int*>(b);
	*c= 7;
	cout << "a: " << a << endl;
	cout << "b: " << *b << endl;
	cout << "c: " << *c << endl;

	cout << "&a: " << &a << endl;
	cout << "&b: " << b << endl;
	cout << "&c: " << c << endl;

在这里插入图片描述 会发现我们并没有真正的改变a的值 虽然他们是同一个地址

显示转换实现

const int a= 2;
const int* b= &a;
int* c= (int*)(b);

未定义const版本的成员函数,我们通常需要使用const_cast来去除const引用对象的const,完成函数调用

void fun(int* key)
{
	cout << key<<endl;
}
void main()
{
	const int a = 10;
	const int *b = &a;
	fun(const_cast<int *>b);
}