C++static_cast下变频有效性

C++ static_cast downcast validity

本文关键字:有效性 cast C++static      更新时间:2023-10-16

static_cast下变频有效吗?

// non-virtual, may be non-trivially copyable
struct Base{
int m_object;
};
// Derived class have only non-virtual functions
struct A : Base{
void arggh(){
std::cout << "Arrghh " << m_object;
}
};
int main() {
Base base{190};
A& a = static_cast<A&>(base);
a.arggh();
return 0;
}

我的意思是,创建基类,然后转换为派生类。

实时

执行下变频的static_cast不执行任何安全检查。由于Base&可能引用A的实例,强制转换继续进行,并且由于它实际上引用的是A,因此我们进入未定义的行为区域*

dynamic_cast则更安全。在引用强制转换的情况下,它将执行检查并抛出异常,或者在指针强制转换的情况下返回nullptr

然而,由于基类缺少任何虚拟函数,dynamic_cast是不可能的,因此您需要至少使用一个虚拟析构函数来修改它:

class Base{
public:
int m_object;
virtual ~Base()=default;
};

现在,如果我们尝试铸造:

A* a = dynamic_cast<A*>(&base);
if (a)
a->arggh();
else
std::cout << "nulln";

我们的输出将是


*相关标准可在[expr.static.cast]中找到:

[对于类似static_cast<D&>(b)的类型转换,其中bD的基类的实例],如果类型为">cv1B"的对象实际上是类型为D的对象的基类子对象,则结果引用类型为D的封闭对象。否则,行为是未定义的。

[expr.dynamic.cast]的相关标准

转换为指针类型失败的值是所需结果类型的空指针值。未能转换为引用类型将引发与类型的处理程序匹配的类型的异常std::bad_cast

否。

并非所有的Base对象都是A1类型,尽管相反,并且static_cast将在方向上工作。


1另一个翻译单元可能有一个继承自Base的类。

一点也不。

假设Base在内存中由这个块[-]表示,A是[-+],在这里你可以看到A包含一个部分Base(带小'-')。

当你创建一个Base时,你有你的[-],然后你把它铸造成a,这意味着你说它实际上是[-+],但[-]之后的内存与[-+]不对应

正如您在本例中所理解的,您可以将A强制转换为Base,因为[-+]包含[-]