繁体   English   中英

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

[英]dynamic_cast “this” to derived type: when is it legal?

这是一个显然不起作用的代码,因为在构造函数中向下转换“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;
}

正如预期的那样,当用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;
}

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

我的直觉是,因为从B的构造函数的主体调用f(),所以“b”已经很好地形成为类型B的实例,这使得代码合法。 然而,我仍然有点像构造函数那样动态播放“this”......

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

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

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

我的问题是:第二个代码是“合法的”

是的,没关系。

我的直觉是,因为从B的构造函数的主体调用f(),所以“b”已经很好地形成为B类的实例,这使得代码合法

无论如何它都是合法的,但这就是断言成功而不是失败的原因:当你在B的构造函数体内时,你有一个B类实例

然而,我仍然有点像构造函数那样动态播放“this”......

请注意, A::f在您调用它的任何地方都是静态良好的形式 - 如果从A::A调用,它将只是动态地使assert失败。 你也可以实例化一个A并直接在它上面调用f (因为A不是抽象的) - 它仍然是格式良好的,但会使assert失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM