在C++中,T q = dynamic_cast<T>(p);构造执行指向p其他指针类型的指针的运行时强制转换,该指针类型T必须出现在动态类型的继承层次结构*p中才能成功.这一切都很好,很好.
但是,也可以执行,它只dynamic_cast<void*>(p)返回指向"最派生对象"的指针(参见C++ 11中的5.2.7 :: 7).我知道这个功能可能在动态转换的实现中免费提供,但它在实践中是否有用?毕竟,它的返回类型充其量void*只是,这有什么用呢?
mit*_*ull 69
该dynamic_cast<void*>()确实可以使用,即使处理多重继承来检查身份.
试试这段代码:
#include <iostream>
class B {
public:
virtual ~B() {}
};
class D1 : public B {
};
class D2 : public B {
};
class DD : public D1, public D2 {
};
namespace {
bool eq(B* b1, B* b2) {
return b1 == b2;
}
bool eqdc(B* b1, B *b2) {
return dynamic_cast<void*>(b1) == dynamic_cast<void*>(b2);
}
};
int
main() {
DD *dd = new DD();
D1 *d1 = dynamic_cast<D1*>(dd);
D2 *d2 = dynamic_cast<D2*>(dd);
std::cout << "eq: " << eq(d1, d2) << ", eqdc: " << eqdc(d1, d2) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
eq: 0, eqdc: 1
Run Code Online (Sandbox Code Playgroud)
请记住,C++允许您以旧的C方式执行操作.
假设我有一些API,我不得不通过该类型走私对象指针void*,但最终传递给它的回调将知道它的动态类型:
struct BaseClass {
typedef void(*callback_type)(void*);
virtual callback_type get_callback(void) = 0;
virtual ~BaseClass() {}
};
struct ActualType: BaseClass {
callback_type get_callback(void) { return my_callback; }
static void my_callback(void *p) {
ActualType *self = static_cast<ActualType*>(p);
...
}
};
void register_callback(BaseClass *p) {
// service.register_listener(p->get_callback(), p); // WRONG!
service.register_listener(p->get_callback(), dynamic_cast<void*>(p));
}
Run Code Online (Sandbox Code Playgroud)
错的!代码是错误的,因为它在存在多重继承时失败(并且不保证在没有的情况下也能工作).
当然,API不是很C++风格,如果我继承,即使是"正确"的代码也可能出错ActualType.所以我不会声称这是一个很好的用途dynamic_cast<void*>,但它是一种用途.