dynamic_cast "this" 到派生类型:什么时候合法?

sun*_*mat 5 c++ inheritance dynamic-cast downcast

这是一个显然不起作用的代码,因为在构造函数中向下转换“this”是非法的:

#include <cassert>

class A {
protected:
        virtual ~A() {}
public:
        A();
};

class B : public A {
};

A::A() {
        assert(dynamic_cast<B*>(this));
}

int main(void) {
        B b;
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,当用 g++ 编译时,断言失败。

然而,这是另一个有效的代码(至少在 g++ 4.7 中,我没有尝试过其他编译器):

#include <cassert>

class A {
protected:
        virtual ~A() {}
public:
        A() {}
        void f();
};

class B : public A {
public:
        B() {
                f();
        }
};

void A::f() {
        assert(dynamic_cast<B*>(this));
}

int main(void) {
        B b;
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:第二个代码是否“合法”,即我可以期望任何编译器都能以这种方式工作吗?

我的直觉是,由于 f() 是从 B 的构造函数的主体中调用的,因此“b”已经很好地形成为类型 B 的实例,这使得代码合法。然而,我仍然有点从构造函数中动态转换“这个”......

(请注意,我的问题不是这是否是好的做法,只是是否合法)。

Mik*_*our 5

是的,第二个示例定义明确,演员表会成功。在 的构造函数中B,对象的动态类型是B,因此强制转换为B*会成功。

在第一个示例中,如您所说,在A动态类型的构造函数中是A,因此强制转换B*将失败。