static_cast

主要有如下几种用法:

  • 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
  • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。(**static_cast** 可用于将 int 转换为 **char**。 但是,得到的 char 可能没有足够的位来保存整个 int 值。 同样,这需要程序员来验证 static_cast 转换的结果是否安全。)
  • 把void指针转换成目标类型的指针(不安全!!)
  • 把任何类型的表达式转换成void类型。(这样的转换通常用于避免编译器发出未使用变量的警告。)
    // static_cast_Operator.cpp
    // compile with: /LD
    class B {};

class D : public B {};

void f(B* pb, D* pd) {
D* pd2 = static_cast<D*>(pb); // Not safe, D can have fields
// and methods that are not in B.

B* pb2 = static_cast<B*>(pd); // Safe conversion, D always
// contains all of B.
}

dynamic_cast:

通常在基类和派生类之间转换时使用
用法:dynamic_cast < type-id > ( expression )

说明:该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。

注意点:
1.dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

2.在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

3.另外要注意:Base要有虚函数,否则会编译出错;static_cast则没有这个限制。

void func(Base *pb)
{
    Derived *pd1 = static_cast<Derived *>(pb);

    Derived *pd2 = dynamic_cast<Derived *>(pb);
}
如果pb实际指向一个Derived类型的对象,pd1和pd2是一样的,并且对这两个指针执行Derived类型的任何操作都是安全的;
如果pb实际指向的是一个Base类型的对象,那么pd1将是一个指向该对象的指针,对它进行Derived类型的操作将是不安全的(如访问m_szName),而pd2将是一个空指针(即0,因为dynamic_cast失败)。

qobject_cast

qobject_cast()函数的行为类似于标准C ++ dynamic_cast()
QObject *obj = new QTimer;          // QTimer inherits QObject

QTimer *timer = qobject_cast<QTimer *>(obj);

// timer == (QObject *)obj

QAbstractButton *button = qobject_cast<QAbstractButton *>(obj);

// button == 0

在使用时有两个限制:
1# 类型必须继承自QObject。
2# 在声明时必须有Q_OBJECT宏。