c – 通过基类函数指针调用派生类

前端之家收集整理的这篇文章主要介绍了c – 通过基类函数指针调用派生类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我可以通过基类函数指针调用派生类,如下例所示?

我理解我的示例有效,但是保证总是这样做(假设对象实际上实现了函数!),或者这只是我正在使用的编译器的特性?

通过这个逻辑,不能简单地从“CBase”(在这种情况下是空的,所以我猜没有开销)派生所有类,并忽略函数指针中的类型?

#include <iostream>

struct CBase
{ 
};

struct CDerived : CBase
{
    void MyFunction()
    {
        std::cout << "Called OK" << std::endl;
    }
};

typedef void (CBase::*FunctionPointer)();


int main()
{
    CDerived* base = new CDerived();

    FunctionPointer pointer = static_cast<FunctionPointer>(&CDerived::MyFunction);
    (base->*pointer)();

    delete base;
}

示例使用场景:
一个派生类,它在基类中带有一个或多个指向“回调”的指针.可以使用派生类来定义回调类型,从而放弃对模板的需求吗?

解决方法

是的,它确保有效.来自[expr.static.cast]:

A prvalue of type “pointer to member of D of type cv1 T” can be converted to a prvalue of type “pointer
to member of B of type cv2 T”,where B is a base class (Clause 10) of D,if cv2 is the same cv-qualification
as,or greater cv-qualification than,cv1.70 If no valid standard conversion from “pointer to member of B of
type T” to “pointer to member of D of type T” exists (4.11),the program is ill-formed. 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.

在这种情况下,我们将指向类型为void()的CDerived成员的指针转换为对于CBase ov类型void()成员的poitner. CBase是包含原始成员的类的基础,因此生成的指针指向原始成员.

来自[expr.mptr.oper]:

Abbreviating pm-expression.*cast-expression as E1.*E2,E1 is called the object expression. If the dynamic
type of E1 does not contain the member to which E2 refers,the behavior is undefined.

在这种情况下,指针指向原始成员. base有那个成员.所以这很好.

请注意,在您的示例中,base实际上是CDerived *.写作同样有效:

CDerived d;
CBase* b = &d;

(b->*pointer)(); // ok - the dynamic type of b contains the member to which pointer refers
原文链接:https://www.f2er.com/c/118675.html

猜你在找的C&C++相关文章