奇怪的铸造产品
Weird product of casting
当我像下面这样投射时,我得到了一些奇怪的东西。我的目的是得到这样的东西:
Inside Base
Inside Derived1
但我得到了无限数量的"内部基地"...这是代码:
#include <iostream>
using namespace std;
template<typename Derived>
class Base
{
public:
virtual void somefunc()
{
cout << "Inside Basen";
static_cast<Derived*>(this)->somefunc();
}
};
class Derived1: public Base<Derived1>
{
public:
void somefunc()
{
cout << "Inside Derived1n";
}
};
int main(int argc, char** argv)
{
Base<Derived1> b1;
b1.somefunc();
return 0;
}
您的代码具有未定义的行为。下面是一个具有相同原理的较短片段:
struct Base { };
struct Derived: Base { int x; };
int main()
{
Base b;
static_cast<Derived &>(b).x = 5;
}
即使不存在x
它仍然未定义,但我添加了它以帮助说明问题。您正在处理对象b
但是内存中的下落5
正在写入吗?
规则是,如果您使用从基类到派生类的static_cast
大小写,则必须检查您正在转换的东西是否实际指向/引用该派生类的实例。如果是,那么它就可以工作;如果不是,那么它是无声的未定义行为。
Mohammad Ali Baydoun关于执行演员表时vtable未更新的陈述是正确的。
当你在main
中呼唤b1.somefunc()
时,因为b1
是一个Base<Derived1>
,Base<Derived1>::somefunc()
会被召唤。当您执行强制转换以Derived1
时,vtable 不会更新,并且要转换的对象在内部仍然是Base<Derived1>
而不是Derived1
。vtable 查找会导致对 Base<Derived1>::somefunc()
的另一个调用而不是Derived1::somefunc()
,结果是无限递归。
但是,这是未定义的行为,因为您要将基类对象强制转换为它不是的东西。 将 Derived1 作为模板参数不会使其成为定义的行为。
相关文章:
- 没有找到相关文章