zoukankan      html  css  js  c++  java
  • c++ cast operator(类型转换操作符)

     复制于:http://xiaochonganty.blog.163.com/blog/static/48527932008931104132748/

    New Cast Operators

    Originally, the C++ standardization committee wanted to deprecate C-style casting, thereby enforcing the use of the new cast operators exclusively. However, because C-style casts are widely used in legacy code and because many C++ compilers serve as C compilers, the committee decided against doing so. That said, C++ programmers are encouraged to use the new cast operators.

    Before I present these operators, let's see why C-style cast has fallen out of favor. Consider the following code listing:

    void *p=&x;int n=(int)p; //C-style cast

    The C-style cast seems harmless at first sight. Yet, it has several potential dangers. First, it performs different operations in different contexts. For example, it may perform a safe int to doublepromotion, but it can also perform inherently dangerous operations such as casting void* to a numeric value (as in the example above). The programmer can't always tell from the source code if the cast is safe or inherently dangerous.

    Worse, a C-style cast may perform multiple operations at once. In the following example, not only does it cast char * to unsigned char *, but it also removes the const qualifier at the same time:

    const char *msg="don't touch!";unsigned char *p=(unsigned char*) msg; // intentional?

    Again, you cannot tell whether this was the programmer's intention or an oversight.

    The New Cast Operators

    The ailments of C-style cast have been known for years. C++ offers a superior alternative in the form of new cast operators. They document the programmer's intent more clearly while preserving the compiler's ability to catch potential bugs like the ones shown above. C++ has four new cast operators:

    static_cast const_cast reinterpret_cast dynamic_cast

    The dynamic_cast operator is unique, as it introduces new functionality that C-style cast doesn't support. I'll get to that momentarily.

    static_cast

    static_cast performs safe and relatively portable casts. For example, you use static_cast to explicitly document a cast that would otherwise take place automatically. Consider the following example:

    bool b=true;int n=static_cast<int> (b);

    C++ automatically casts bool to int in this context so the use of static_cast in this case isn't necessary. However, by using it, programmers document their intention explicitly.

    In other contexts, static_cast is mandatory. For example, when you cast void* to a different pointer type, as in the following example:

    int n=4;void *pv=&n;int pi2 = static_cast<int *> (pv); //mandatory

    static_cast uses the information available at compile time to perform the required type conversion. Therefore, the target and the source might not be identical in their binary representation. Consider a float to int conversion. The binary representation of the floating number 10.0 is quite different from the equivalent integer value of 10. static_cast performs the necessary adjustments when casting one to the other.

    The use of static_cast enables the compiler to catch programmers' mistakes such as this:

    const char *msg="don't touch!";unsigned char *p= static_cast<unsigned char*> (msg); //error

    Here the compiler issues an error message indicating that the cast operation attempts to remove the const qualifier of msg -- something that the programmer probably didn't intend anyway.

    const_cast

    The removal of const requires a special cast operator called const_cast. This operator may perform only the following operations:

    Remove the const and or volatile qualification;Add const and or volatile qualification

    For example

    struct A{ void func(){} // non-const member function};void f(const A& a) { a.func(); // error, calling a non-const function }

    Clearly, this is a design mistake. The member function func() should have been declared constin the first place. However, such code does exist in third-party libraries; when innocent programmers try to use it, they have to resort to brute force casts. To overcome this problem, you may remove theconst qualifier of a and then call func() as follows:

    A &ref = const_cast<A&> (a); // remove constref.func(); // now fine

    Trying to perform any other conversion with const_cast will result a compilation error. Remember also that while const_cast may remove the const qualifier of an object, this doesn't mean that you're allowed to modify it. In fact, trying to modify a const object causes undefined behavior. Therefore, useconst_cast cautiously when it is used for the removal of const or volatile.

    reinterpret_cast

    As opposed to static_castreinterpret_cast performs relatively dangerous and nonportable castsreinterpret_cast doesn't change the binary representation of the source object. Therefore, it is often used in low-level applications that convert objects and other data to a stream of bytes (and vice versa). In the following example, reinterpret_cast is used to "cheat" the compiler, enabling the programmer to examine the individual bytes of a float variable:

    float f=10;unsigned char *p = reinterpret_cast <unsigned char*> (&f);for (int j=0; j<4; ++j) cout<<p[j]<<endl;

    The use of reinterpret_cast explicitly warns the reader that an unsafe (and probably a nonportable) conversion is taking place. When using reinterpret_cast, the programmer -- rather than the compiler -- is responsible for the results.

    dynamic_cast

    As previously said, dynamic_cast differs from all other three cast operators. You use it when the conversion must access the runtime type information of an object rather than its static type (for more information on static vs. dynamic typing, please refer to the "Runtime Type Information (RTTI)" section). Two common scenarios that necessitate the use of dynamic_cast are a <I>downcast</i> i.e., casting a base class pointer or reference to a pointer or reference of a derived class and a crosscast in which the programmer converts a multiply-inherited object to one of its secondary base classes.

    Summary

    C-style cast is neither safe nor explicit enough, as I have shown. It disables the compiler's type-safety checks, its syntactic form doesn't express the intended conversion clearly, and it cannot perform a dynamic cast. For all these reasons, you should avoid using it in new code.

    Instead, use static_cast for safe and rather portable casts, const_cast to remove or add only the const/volatile qualifiers of an object, and reinterpret_cast for low-level, unsafe and nonportable casts. Use dynamic_cast for conversions that must access the dynamic type of an object and RTTI capability-queries.

    其他参考http://en.wikibooks.org/wiki/C%2B%2B_Programming/Type_Casting

    http://welfare.cnblogs.com/articles/336091.html

    http://www.acm.org/crossroads/xrds3-1/ovp3-1.html

  • 相关阅读:
    deep_learning_Function_numpy_random.normal()
    deep_learning_Function_np.newaxis参数理解
    deep_learning_Function_numpy.linspace()
    deep_learning_Function_tf.identity()
    deep_learning_Function_tf.control_dependencies([])
    deep_learning_Function_tf.train.ExponentialMovingAverage()滑动平均
    deep_learning_Function_bath_normalization()
    deep_learning_PCA主成分分析
    deep_learning_Function_numpy_argmax()函数
    deep_learning_Function_matpotlib_scatter()函数
  • 原文地址:https://www.cnblogs.com/xaf-dfg/p/3805461.html
Copyright © 2011-2022 走看看