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;
}
原文地址:https://www.cnblogs.com/logchen/p/10166677.html