Upcasting and Downcasting

  • Upcasting is an operation that creates a base class reference from a subclass reference. (subclass -> superclass) (i.e. Manager -> Employee)

    Employee emp = (Employee)mgr; //mgr is Manager
    

    We can think of up in word upcasting as more abstract or more generic.

  • Downcasting is an operation that creates a subclass reference from a base class reference. (superclass -> subclass) (i.e. Employee -> Manager)

    Employee m = new Manager();
    Employee e = new Employee();
      
    if(m is Manager) Console.WriteLine("m is a manager");
    if(e is Manager) Console.WriteLine("e is a manager");
    

    Downcasting refers to the procedure of using a base class pointer to an object and querying it at run time to find out type information, used to explicitly cast the pointer to a subclass pointer so that the subclass API can be used.

    We can think of down in word downcasting as more concrete or more specific.

Cast in C++

C++类型转换分为显式类型转换和隐式类型转换 ,隐式类型转换由编译器自动完成,这里只讨论显式类型转换。

旧式风格的类型转换

type(expr); // 函数形式的强制类型转换
(type)expr; // C语言风格的强制类型转换

现代C++风格的类型转换

cast-name<type>(expression)

static_cast

Condition 1: static_castis the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating static_cast isn't necessary. For example:

float a = int(5);

Condition 2: static_cast can also cast through inheritance hierarchies, For example:

void *p = &d;
double *dp = static_cast<double*>(p);

static_cast doesn't do checking.

dynamic_cast

What is a polymorphic type?

A class having at least one virtual function is called a polymorphic type. This can be only a destructor also.

So the following is a polymorphic type:

struct Test {
  virtual ~Test();
};

dynamic_cast is exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited).

相比static_castdynamic_cast会在运行时检查类型转换是否合法,具有一定的安全性。由于运行时的检查,所以会额外消耗一些性能。dynamic_cast使用场景与static_cast相似,在类层次结构中使用时,上行转换和static_cast没有区别,都是安全的;下行转换时,dynamic_cast会检查转换的类型,相比static_cast更安全。

// 下行转换
class A { virtual void f(){}; };
class B : public A{ };
void main()
{
     A* pA = new B;
     B* pB = dynamic_cast<B*>(pA); 
}

注意类A和类B中定义了一个虚函数,这是不可缺少的。因为类中存在虚函数,说明它可能有子类,这样才有类型转换的情况发生,由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。

Reference