Mik*_*ine 36 c++ casting undefined-behavior language-lawyer
如果我从Base转换为Derived类型,但Base类型不是派生类型的实例,但只使用结果,是否会得到未定义的行为?
很难理解我在问什么?看看这个例子:
struct Animal { int GetType(){...} };
struct Dog : Animal { bool HasLoudBark(){...}};
struct Cat : Animal { bool HasEvilStare(){...} };
Animal * a = ...;
Dog* d = static_cast<Dog*>(a);
if(a->GetType() == DogType && d->HasLoudBark())
....
Run Code Online (Sandbox Code Playgroud)
在这种情况下a可能或不是Dog.我们总是做static_cast的a到Dog * d,但我们从来不使用d,除非我们确定它的一个Dog.
假设a不是a Dog,那么在演员阵容中这个未定义的行为是什么?或者它被定义为我们实际上没有使用,d除非它真的是一个Dog?
赞赏参考标准的相关部分.
(是的,我知道我可以使用dynamic_cast和RTTI,可能这不是很好的代码,但我对这是否有效更感兴趣)
Rei*_*ica 36
演员本身有不确定的行为.引用C++ 17(n4659)[expr.static.cast] 8.2.10/11:
类型为"指向cv1的 指针"的prvalue
B,其中B是一个类类型,可以转换为类型为"指向cv2的 指针"的prvalueD,其中D是一个派生类(第13条)B,如果cv2是相同的cv-qualification,则或者比cv1更高的cv资格....如果"指向cv1的 指针B" 类型的prvalue指向B实际上是类型对象的子对象D,则生成的指针指向类型的封闭对象D.否则,行为未定义.
YSC*_*YSC 12
这是未定义的行为,但(足够有趣)如果你会使用reinterpret_cast而不是static_cast,你会把那个恶魔赶走.
可以将对象指针显式转换为不同类型的对象指针.当对象指针类型的prvalue v转换为对象指针类型"指向
cv T"时,结果为static_cast<cv T*>(static_cast<cv void*>(v)).
正如用户Angew所指出的,这"需要特定的内部表示,以确保static_cast<void*>(d) == static_cast<void*>(a)何时a == d".
这表示[class.mem]/22为26:
如果标准布局类对象具有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同(如果该成员不是位字段).它的地址也与每个基类子对象的地址相同.
因此,如果GetType()的Animal返回一个非静态数据成员的从值公共初始序列的Animal和Dog,该行为被定义.
处理简单继承和默认对齐对象时,满足这些要求.
| 归档时间: |
|
| 查看次数: |
2037 次 |
| 最近记录: |