这后一个例子表明一个单一的对象(例如,一个类型为 Derived 的对象)可能会有不止一个地址(例如,它的被一个 Base* 指针指向的地址和它的被一个 Derived* 指针指向的地址)。这在 C 中就不会发生,也不会在 Java 中发生,也不会在 C# 中发生,它仅在 C++ 中发生。实际上,如果使用了多继承,则一定会发生,但是在单继承下也会发生。与其它事情合在一起,就意味着你应该总是避免对 C++ 如何摆放事物做出假设,你当然也不应该基于这样的假设执行强制转型。例如,将一个对象的地址强制转型为 char* 指针,然后对其使用指针运算,这几乎总是会导致未定义行为。
但是请注意我说一个偏移量是“有时”被需要。对象摆放的方法和他们的地址的计算方法在不同的编译器之间有所变化。这就意味着仅仅因为你的“我知道事物是如何摆放的”而使得强制转型能工作在一个平台上,并不意味着它们也能在其它平台工作。这个世界被通过痛苦的道路学得这条经验的可怜的程序员所充满。 关于强制转型的一件有趣的事是很容易写出看起来对(在其它语言中也许是对的)实际上错的东西。例如,许多应用框架(application framework)要求在派生类中实现虚成员函数时要首先调用它们的基类对应物。假设我们有一个 Window 基类和一个 SpecialWindow 派生类,它们都定义了虚函数 onResize。进一步假设 SpecialWindow 的 onResize 被期望首先调用 Window 的 onResize。这就是实现这个的一种方法,它看起来正确实际并不正确:
class Window { // base class
public:
virtual void onResize() { ... } // base onResize impl
...
};
class SpecialWindow: public Window { // derived class
public:
virtual void onResize() { // derived onResize impl;
static_cast(*this).onResize(); // cast *this to Window,
// then call its onResize;
// this doesn’t work!
|
您将承担一切因您的行为、言论而直接或间接导致的民事或刑事法律责任
留言板管理人员有权保留或删除其管辖留言中的任意内容 本站提醒:不要进行人身攻击。谢谢配合。 |