zoukankan      html  css  js  c++  java
  • C++进阶--显式类型转换(casting)

    //############################################################################
    /*
     * 显式类型转换
     *
     * 类型转换
     *    1. 隐式
     *    2. 显式 - Casting
     */
    
    /*
     * 1. static_cast
     */
    int i = 9;
    float f = static_cast<float>(i);  // 将对象从一个类型转为另一个类型
    dog d1 = static_cast<dog>(string("Bob"));  // 需要定义类型转换函数
    dog* pd = static_cast<dog*>(new yellowdog()); // 将指针/引用从一个类型转为一个相关的类型(down/up cast)
                                                 
    /*
     * 2. dynamic_cast 
     */
    dog* pd = new yellowdog();
    yellowdog py = dynamic_cast<yellowdog*>(pd); 
    // a. 将指针/引用从一个类型转为一个相关的类型(down cast)   只能用于指针和引用,基本上用于基类转成派生类
    // b. 运行时类型检查。如果成功, py==pd; 如果失败, py==0;
    // c. 要求2个类型是多态的 (有虚函数).
    
    /*
     * 3. const_cast
     */                                        // 只能用于指针和引用
    const char* str = "Hello, world.";         // 只能用于同一类型
    char* modifiable = const_cast<char*>(str); // 去除所指的对象的const属性 
     
    
    /*
     * 4. reinterpret_cast
     */
    long p = 51110980;                   
    dog* dd = reinterpret_cast<dog*>(p);  // 重新解释所指对象的比特位
    // 可以将指针转成任意其他类型的指针
    
    /*
     * C-Style Casting:  
     */
    short a = 2000;
    int i = (int)a;  // c-like cast表示法
    int j = int(a);   // 类函数表示法
    //   是static_cast, const_cast and reinterpret_cast的混合
    
    
    /*
     * 更倾向于C++风格的转换,因为:
     * 1. 更具倾向性,代码易于阅读
     * 2. 更少的使用错误. C++风格提供:
     *    a. 每种转换具有更窄的目的
     *    b. 运行时检查能力
     */
    
    
    
    /*
     * 转换有风险
     *
     * dynamic_cast的例子:
     */
    class dog {
       public:
       virtual ~dog() {}
    };
    
    class yellowdog : public dog {
       int age;
       public:
       void bark() { cout<< "woof. I am " << age  << endl; } //bark没有访问任何成员数据,编译器会试图将其解释为静态函数处理
    };
    
    int main() {
       dog* pd = new dog();
       yellowdog* py = dynamic_cast<yellowdog*>(pd);    //运行时类型检查开销很大
       py->bark();      //所以这里可以成功
       cout << "py = " << py << endl;
       cout << "pd = " << pd << endl;
       ...
    }
    
    OUTPUT:
    woof.
    py = 0
    pd = 57873400
    
    
    /* 转换可以是一个方便的黑客工具 */
    
    class dog {
    	public:
    	std::string m_name;
    	dog():m_name("Bob") {}
    	void bark() const { //*this is const
    	  std::cout << "My name is " << m_name << std::endl;
    	}
    };
    
    
    //	  m_name = "Henry";
    //	  const_cast<dog*>(this)->m_name = "Henry";
    
    
    
    /* 【各类转换的比较】
     * Generate_Code 转换是否会产生相当数据的可执行代码
     * Generate_date 转换是否会产生不同的数据类型
     * risky 风险等级
     * data_type 可用于哪些类型
     * =========================================  C++ 风格转换 ================================
     *                                  Generate_Code   Generate_data             risky      data_type
     * Object Casting:            
     *    static_cast                    yes                    yes                  2       any types
     *                                                                                       (as long as type 
     *                                                                                       conversion is defined)
     * Pointer/Reference Casting:
     *    static_cast                     no                     no                  4        related types
     *    dynamic_cast                   yes                     no                  3        related types(down-cast)
     *    const_cast                     no                     no                  1         same type
     *    reinterpret_cast               no                     no                  5         any types
     *
     *
     *
     *
     * =========================================  C 风格转换 ================================
     *                                    Generate_Code  Generate_data             risky      data_type
     * Object Casting:                    yes                 yes                    5        any types
     *                                                                                        (as long as type 
     *                                                                                        conversion is defined)
     * Pointer/Reference Casting:         no                   no                    5        any types
     *
     *
     * 
     *
     * 注意:
     * 1. const_cast, dynamic_cast和reinterpret_cast只能用于指针/引用
     * 2. 对象的static_cast和指针的static_cast差别非常大
     * 3. reinterpret_cast从比特上重新分配类型信息,用在低层的编码上
     * 4. dynamic_cast相比static_cast加上了运行时类型检查
     * 5. dynamic_cast和static_cast指针转换时只能转成有关的类型 (即, 基类 <-> 派生类之间转换).
     *
     */
    
    /* 使用多态最小化转换的使用
        如下例子的转换,可以用多态实现
    */
    
    class dog {
       public:
       virtual ~dog() {}
    };
    
    class yellowdog : public dog {
       public:
       void bark() { cout<< "Yellow dog rules! "  << endl; }
    };
    
    int main() {
       dog* pd = get_dog();
       if (yellowdog *py = dynamic_cast<yellowdog*>(pd)) {
          py->bark();
       }
       delete pd;
    }
    
    /* 增加虚函数bark()*/
    
    class dog {
       public:
       virtual ~dog() {}
       virtual void bark() {}
    };
    
    class yellowdog : public dog {
       public:
       void bark() { cout<< "Yellow dog rules! "  << endl; }
    };
    
    int main() {
       dog* pd = get_dog();
       pd->bark();
       delete pd;
    }
    
  • 相关阅读:
    Linux内核分析作业六
    课本第三章读书笔记
    课本第十八章读书笔记
    Linux内核分析作业五
    课本第五章读书笔记
    MSF MS11-050/10-087/Adobe攻击实践及内存保护技术
    Linux课题实践五——字符集总结与分析
    Linux课题实践四——ELF文件格式分析
    Linux课题实践三——程序破解
    实践二——内核模块
  • 原文地址:https://www.cnblogs.com/logchen/p/10166677.html
Copyright © 2011-2022 走看看