C++类型转换运算符(Type Conversion Operators)
C++类型转换运算符(Type Conversion Operators)
1.static_cast
将一个值以合逻辑的方式转换。着可以看做是"利用原值重新构造一个临时对象,并在设立初值的时候使用类别转换"。唯有当上述的类型转换有所定义,整个转换才会成功。
所谓的"有所定义",可以是语言内建规则,也可以是程序员自定的转换动作。
eg:
#include <iostream>
using namespace std;
int main()
{
float f = 100.555;
cout << static_cast<int>(f)<<endl;
return 0;
}
将多态型别(polymorphic type)向下转型(downcast)为其实际静态类型(real static type)。
这是唯一在运行期进行检验的转型动作。你可以用它来检验某个多态对象的类型(polymorphic value)。
eg:
#include <iostream>
using namespace std;
class Car
{
public:
virtual void function()
{
}
};
class Cabriolet:public Car
{
public:
virtual void function()
{
cout << "Cabriolet::function" << endl;
}
};
class Limousine:public Car
{
public:
virtual void function()
{
cout << "Limousine::function" << endl;
}
};
void func(Car* cp)
{
Cabriolet* p = dynamic_cast<Cabriolet*> (cp);
if(p == NULL)
{
cout << "did not refer to an object of type Cabriolet" << endl;
}
else
{
cout << "can refer to an object of type Cabriolet" << endl;
}
Limousine* p2 = dynamic_cast<Limousine*>(cp);
if(p2 == NULL)
{
cout << "did not refer to an object of type Limousine" << endl;
}
else
{
cout << "can refer to an object of type Limousine" << endl;
}
cout << endl;
}
int main()
{
Car car;
Cabriolet cabriolet;
Limousine limousine;
func(&car);
func(&cabriolet);
func(&limousine);
return 0;
}
运行结果为:
did not refer to an object of type Cabriolet
did not refer to an object of type Limousine
can refer to an object of type Cabriolet
did not refer to an object of type Limousine
did not refer to an object of type Cabriolet
can refer to an object of type Limousine
Process returned 0 (0x0) execution time : 0.078 s
Press any key to continue.
eg:
struct A {
virtual void f() { }
};
struct B : public A { };
struct C { };
void f () {
A a;
B b;
A* ap = &b;
B* b1 = dynamic_cast<B*> (&a); // NULL, because 'a' is not a 'B'
B* b2 = dynamic_cast<B*> (ap); // 'b'
C* c = dynamic_cast<C*> (ap); // NULL.
A& ar = dynamic_cast<A&> (*ap); // Ok.
B& br = dynamic_cast<B&> (*ap); // Ok.
C& cr = dynamic_cast<C&> (*ap); // std::bad_cast
}
在这个例子中,面对实际的静态类别为Cabriolet的物件,f()有特殊的应对行为。当参数是一个reference,而且类别转换失败时,dynamic_cast丢出一个bad_cast异常。
注意,从设计者角度而言,你应该运用多态技术的程序中,避免这种"程序行为取决于具体类型 "的写法。
3.const_cast
设定或取出类别的常数性,亦可除volatile饰词。除此之外不允许任何转换。
eg:
#include <iostream>
using namespace std;
void f(int* p)
{
cout << *p << endl;
}
int main(void) {
const int a = 10;
const int* b = &a;
// Function f() expects int*, not const int*
// f(b);
int* c = const_cast<int*>(b);
f(c);
// Lvalue is const
// *b = 20;
// Undefined behavior
// *c = 30;
int a1 = 40;
const int* b1 = &a1;
int* c1 = const_cast<int*>(b1);
// Integer a1, the object referred to by c1, has
// not been declared const
*c1 = 50;
cout << *c1 << endl;
return 0;
}
The compiler will not allow the function call f(b). Function f() expects a pointer to an int, not a const int. The statement
int* c = const_cast<int>(b) returns a pointer c that refers to a without the const qualification of a. This process of using
const_cast to remove the const qualification of an object is called casting away constness. Consequently the compiler will
allow the function call f(c).
The compiler would not allow the assignment *b = 20 because b points to an object of type const int. The compiler will allow
the *c = 30, but the behavior of this statement is undefined. If you cast away the constness of an object that has been
explicitly declared as const, and attempt to modify it, the results are undefined.
However, if you cast away the constness of an object that has not been explicitly declared as const, you can modify
it safely. In the above example, the object referred to by b1 has not been declared const, but you cannot modify
this object through b1. You may cast away the constness of b1 and modify the value to which it refers.
4.reinterpret_cast
此运算符的行为由编译器定义。可能重新解释bits意义,但也不一定如此。使用此一转型动作通常带来不可移植性。
The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types.
这些操作符取代了以往小圆括号所代表的旧式转型,能够清楚阐明转型的目的。小圆括号转型可替换dynamic_cast之外的其他三种转型,也因此你运用它时,你无法明确显示用它的确切理由。
这些新式转型操作符给了编译器更多的信息,让编译器清楚知道转型的理由,并在转型失败时释出一份错误报告。
参考资料:
《C++标准程序库》侯捷 孟岩译
http://www.cppreference.com/wiki/keywords/dynamic_cast
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/keyword_const_cast.htm
http://www.cppreference.com/wiki/keywords/reinterpret_cast
本文完
转载请表明出处,谢谢
2010-08-19
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器