假设我有一个指针类型,它可以保存基类方法的地址。我可以将子类方法的地址分配给它并期望它正常工作吗?在我的情况下,我将它与基类指针一起使用,对象的动态类型是派生类。
struct B
{
typedef void (B::*MethodPtr)();
};
struct D: public B
{
void foo() { cout<<"foo"<<endl; }
};
int main(int argc, char* argv[])
{
D d;
B* pb = &d;
//is the following ok, or undefined behavior?
B::MethodPtr mp = static_cast<B::MethodPtr>(&D::foo);
(pb->*mp)();
}
标准在谈到 static_cast 时这样说:
5.2.9.9“指向类型为 cv1 T 的 D 成员的指针”类型的右值可以转换为类型为“指向类型为 cv2 T 的 B 成员的指针”类型的右值,其中 B 是 D 的基类(第 10 条),如果存在从“指向 T 类型 B 成员的指针”到“指向 T 类型 D 成员的指针”的有效标准转换 (4.11),并且 cv2 与 cv1 具有相同的 cv 限定或大于 cv1 的 cv 限定。63)将空成员指针值(4.11)转换为目标类型的空成员指针值。如果类 B 包含原始成员,或者是包含原始成员的类的基类或派生类,则指向成员的结果指针指向原始成员。否则,强制转换的结果是未定义的。[注意:虽然 B 类不需要包含原始成员,取消引用指向成员的指针的对象的动态类型必须包含原始成员;见 5.5。]
与往常一样,我很难破译标准。它有点说没关系,但我不能 100% 确定上述文本是否真的适用于我的示例代码中的情况。