gpt4 book ai didi

c++ - "upcast"方法指针并将其与基类指针一起使用是否安全?

转载 作者:可可西里 更新时间:2023-11-01 15:20:47 26 4
gpt4 key购买 nike

假设我有一个可以保存基类方法地址的指针类型。我可以将子类方法的地址分配给它并期望它正常工作吗?在我的例子中,我将它与基类指针一起使用,对象的动态类型是派生类。

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 An rvalue of type “pointer to member of D of type cv1 T” can be converted to an rvalue of type “pointer to member of B of type cv2 T”, where B is a base class (clause 10) of D, if a valid standard conversion from “pointer to member of B of type T” to “pointer to member of D of type T” exists (4.11), and cv2 is the samecv-qualification as, or greater cv-qualification than, cv1. 63) The null member pointer value (4.11) is converted to the null member pointer value of the destination type. If class B contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member. Otherwise, the result of the cast is undefined. [Note: although class B neednot contain the original member, the dynamic type of the object on which the pointer to member is dereferenced must contain the original member; see 5.5.]

一如既往,我很难解读标准。它有点说没关系,但我不能 100% 确定上面的文字是否真的适用于我的示例代码中的情况。

最佳答案

这是有效的。

If class B contains the original member,

B 不包含 D::Foo,所以没有。

or is a base [...] of the class containing the original member

B 是 D 的基,因此成立。结果:

the resulting pointer to member points to the original member

条款 5.2.9 9 说只有当你也可​​以向下转型时你才能向上转型,如 § 4.11 中所指定:

An rvalue of type “pointer to member of B of type cv T,” where B is a class type, can be converted to an rvalue of type “pointer to member of D of type cv T,” where D is a derived class (clause 10) of B. If B is an inaccessible (clause 11), ambiguous (10.2) or virtual (10.1) base class of D, a program that necessitates this conversion is ill-formed.

这只是说只要 B 是可访问的、不是虚拟的并且在 D 的继承图中只出现一次就可以向下转型。

向上转换方法指针的内在危险是您可以在实际类型为 B 的对象上调用 mp。只要处理 D::* 的代码块也处理 D* ,您可以避免这种情况。

关于c++ - "upcast"方法指针并将其与基类指针一起使用是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4272909/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com