[英]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.