博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dynamic/Static/Reinterpret/Const and Volatile Cast (English)
阅读量:3974 次
发布时间:2019-05-24

本文共 7071 字,大约阅读时间需要 23 分钟。

Const and Volatile Cast

The expression
const_cast<T>(v) can be used to change the "const" or "volatile" qualifiers of pointers or references.
T must be a pointer, reference, or pointer to member type. If
cv1 and
cv2 are some combination of
const and
volatile qualifiers (that is,
cv1 is
volatile and
cv2 is
const volatile),
const_cast can convert a value of type "pointer to
cv1
T" to "pointer to
cv2
T", or "pointer to member of type
cv1
T" to "pointer to member of type
cv2
T". If we have an lvalue of type
cv1 T, then
const_cast can convert it to "reference to type
cv2
T". (An lvalue names an object in such a way that its address can be taken.)
class A { public: virtual void f();                      int i; };    extern const int A::* cimp;    extern const volatile int* cvip;    extern int* ip;    void use_of_const_cast( )        { const A a1;          const_cast
(a1).f( ); // remove const a1.*(const_cast
cimp) = 1; // remove const ip = const_cast
cvip; } // remove const and volatile

Reinterpret Cast

The expression
reinterpret_cast<T>(v)changes the interpretation of the value of the expression
v. It will convert from pointer types to integers and back again, between two unrelated pointers, pointers to members, or pointers to functions. The only guarantee on such casts is that a cast to a new type, followed by a cast back to the original type, will have the original value. It is legal to cast an lvalue of type
T1 to type
T2& if a pointer of type T1* can be converted to a pointer of type
T2* by a
reinterpret_cast.
reinterpret_cast cannot be used to convert between pointers to two different classes that are related by inheritance (use
static_cast or
dynamic_cast), nor can it be used to cast away
const (use
const_cast).
class A { public: virtual void f( ); };    void use_of_reinterpret_cast( )        { A a1;          const A a2;          int i = reinterpret_cast
(&a1); // grab address const int j = reinterpret_cast
(&a2); } // grab address

Static Cast

The expression
static_cast<T>(v) converts the value of the expression
v to that of type
T. It can be used for any cast that is performed implicitly on assignment. In addition, any value may be cast to
void, and any implicit cast can be reversed if that cast would be legal as an old-style cast. It cannot be used to cast away
const.
class B            { public: virtual void g( ); };    class C : public B { public: virtual void g( ); };      void use_of_static_cast( )        { C c;          // an explicit temporary lvalue to the base of c, a B          B& br = c;          br.g( );   // call B::g instead of C::g          // a static_cast of an lvalue to the base of c, a B          static_cast
(c).g( ); } // call B::g instead of C::g

Dynamic Cast

A pointer or reference to a class can actually point to any class publicly derived from that class. Occasionally, it may be desirable to obtain a pointer to the fully-derived class, or to some other base class for the object. The dynamic cast provides this facility.
The dynamic type cast will convert a pointer or reference to one class into a pointer or reference to another class. That second class must be the fully-derived class of the object, or a base class of the fully-derived class.
In the expression
dynamic_cast<T>(v),
v is the expression to be cast, and
T is the type to which it should be cast.
T must be a pointer or reference to a complete class type, or "pointer to
cv
void", where
cv is [
const][
volatile]. In the case of pointer types, if the specified class is not a base of the fully
derived class, the cast returns a null pointer. In the case of reference types, if the specified class is not a base of the fully derived class, the cast throws a
bad_cast exception. For example, given the class definitions:
class A          { public: virtual void f( ); };    class B          { public: virtual void g( ); };    class AB :       public virtual A, private B { };
The following function will succeed.
void simple_dynamic_casts( )        { AB  ab;          B*  bp  = (B*)&ab;  // cast needed to break protection          A*  ap  = &ab;      // public derivation, no cast needed          AB& abr = dynamic_cast
(*bp); // succeeds ap = dynamic_cast
(bp); assert( ap != NULL ); bp = dynamic_cast
(ap); assert( bp == NULL ); ap = dynamic_cast
(&abr); assert( ap != NULL ); bp = dynamic_cast
(&abr); assert( bp == NULL ); }
In the presence of virtual inheritance and multiple inheritance of a single base class, the actual dynamic cast must be able to identify a unique match. If the match is not unique, the cast fails. For example, given the additional class definitions:
class AB_B :     public AB,        public B  { };    class AB_B__AB : public AB_B,      public AB { };
The following function will succeed:
void complex_dynamic_casts( )        {          AB_B__AB ab_b__ab;          A*ap = &ab_b__ab;                        // okay: finds unique A statically          AB*abp = dynamic_cast
(ap); // fails: ambiguous assert( abp == NULL ); // STATIC ERROR: AB_B* ab_bp = (AB_B*)ap; // not a dynamic cast AB_B*ab_bp = dynamic_cast
(ap); // dynamic one is okay assert( ab_bp != NULL ); }
The null-pointer error return of
dynamic_cast is useful as a condition between two bodies of code, one to handle the cast if the type guess is correct, and one if it is not.
void using_dynamic_cast( A* ap )        {          if ( AB *abp = dynamic_cast
(ap) ) { // abp is non-null, // so ap was a pointer to an AB object // go ahead and use abp process_AB( abp ); } else { // abp is null, // so ap was NOT a pointer to an AB object // do not use abp process_not_AB( ap ); }
If run-time type information has been disabled, i.e.
-features=no%rtti, (See Chapter 5, "RTTI"), the compiler converts
dynamic_cast to
static_cast and issues a warning.
If exceptions have been disabled (See Chapter 4, "Exception Handling"), the compiler converts
dynamic_cast<T&> to
static_cast<T&> and issues a warning. The dynamic cast to a reference may require an exception in normal circumstances.
Dynamic cast is necessarily slower than an appropriate design pattern, such as conversion by virtual functions. See
Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma et al.

转载地址:http://exhki.baihongyu.com/

你可能感兴趣的文章
git基本使用
查看>>
七、WordPress配置HTTPS与开启CDN加速
查看>>
CentOS 6.7下MySQL 5.6 yum快速安装及参数详解
查看>>
CentOS6.8二进制安装MySQL5.6
查看>>
centos 6x系统下源码安装mysql操作记录
查看>>
Centos搭建Mysql主从复制
查看>>
centos下部署redis服务环境及其配置说明
查看>>
Centos7下部署两套python版本并存环境的操作记录
查看>>
利用阿里云的源yum方式安装Mongodb
查看>>
Mysql的二进制日志binlog的模式说明
查看>>
zabbix监控交换机、防火墙等网络设备
查看>>
Redis数据"丢失"讨论及规避和解决的几点总结
查看>>
Redis日常操作命令小结
查看>>
线程安全的单例模式
查看>>
fastjson深度源码解析- 序列化(五) - json内部注册序列化解析
查看>>
fastjson深度源码解析- 序列化(六) - json特定序列化实现解析
查看>>
fastjson深度源码解析- 词法和语法解析(二) - 基础类型实现解析
查看>>
fastjson深度源码解析- 词法和语法解析(三) - 针对对象实现解析
查看>>
fastjson深度源码解析- 反序列化(一) - 反序列化解析介绍
查看>>
fastjson深度源码解析- 反序列化(二) - 内部注册反序列化解析
查看>>