C++ - 基类指针,方法指针,指派生类,方法?

Posted

技术标签:

【中文标题】C++ - 基类指针,方法指针,指派生类,方法?【英文标题】:C++ - Base class pointer, method pointer, refer to derived class, method? 【发布时间】:2014-04-01 06:00:24 【问题描述】:
class Base

    virtual void Foo()
    virtual void Bar()
;

class Derived1 : public Base

    void Foo() //Do something 
    void Bar() //Do something 


class Derived2 : public Base

    void Foo() //Do something 
    void Bar() //Do something 


class OtherClass

public:
    Base* obj;
    void (Base::*method)();

    void Add( Base* _obj, void (Base::*_method)() )
    
        obj = _obj;
        method = _method;
    

    void Run()
    
        ( obj->method )();
    


int main()

    Derived1 d1;
    Derived2 d2;

    OtherClass other;

    other.Add( &d1, &(Derived1::Foo) );
    //other.Add( &d2, &(Derived2::Bar) ); etc, etc.

    other.Run();

我的问题:

假设我有一个带有方法的派生类,我可以使用该类的基类型指针来引用该类的实例。假设我知道我想调用什么方法,然后我可以通过该指针调用它,派生类的方法将被调用。

当我通过提供方法指针指定要调用的方法时,如何实现类似的多态行为?

如果我转换方法指针,上面所基于的真实代码将编译,但它似乎没有做任何事情——此时我意识到我没有调用 OtherClass 的更新方法,即为什么我没有得到任何快乐。 :D 所以这行得通,就像(几乎)一样。愚蠢,愚蠢的大脑。

然后稍微修正一下:现在我需要将传递给 OtherClass 的方法指针静态转换为当我传递给 Add 时指向 Base 类方法的指针。这并不理想。

如果我将 &(Base::Foo) 传递给例如方法 Add,我能否获得相同的行为?

如果我在指向派生类型实例的基类型指针上调用该方法,是否会调用 Derived1::Foo?

我感觉它会呼叫基地成员。 :(

一些阅读: Is it safe to "upcast" a method pointer and use it with base class pointer? C++ inheritance and member function pointers Pointer to member conversion Casting a pointer to a method of a derived class to a pointer to a method of a base class

【问题讨论】:

Something 告诉我您的大部分问题都可以通过在您发布的代码的成员中实际执行某些操作(例如向标准输出发送消息)来回答,而不是用它们的闭合花括号来结束它们行注释。 并且不要静态转换指针。只需传递基类方法指针。如果虚拟继承设置正确(and in this case, it is),派生成员将被触发。 我最初是在寻找不同的答案,但在中途解决了我自己的问题,决定更改问题,所以我理解您为什么发布该评论但当时我的真实代码正在做某事而没有正在发生。我可能可以通过一些实验来回答这个新问题,但我正在上班,并且已经输入了大部分帖子。 :) 另外,我认为它值得在网站上使用。不过,您的第二条评论很棒,这是一个很好的工具。将其发布为答案,我会标记它,@WhozCraig 哦,那很好。我没有将其发布为答案,因为我不确定这就是您所期待的。即传递虚拟基础成员的 member-fn-ptr 会触发适当的派生成员。我希望那是你要去的地方。是的,Coliru 和 Ideone 都非常适合现成的代码剪断。两者都在这里经常使用。 【参考方案1】:

我相信您正在考虑,如果在派生类中提供,虚拟基的 member-fn-ptr 是否会触发多态派生覆盖。如果是这样,答案是肯定的,下面的代码演示了这一点。

希望这会有所帮助。

#include <iostream>

class Base

public:
    virtual void Foo()
    
        std::cout << __PRETTY_FUNCTION__ << '\n';
    
    virtual void Bar()
    
        std::cout << __PRETTY_FUNCTION__ << '\n';
    
;

class Derived1 : public Base

public:
    void Foo()
    
        std::cout << __PRETTY_FUNCTION__ << '\n';
    

    void Bar()
    
        std::cout << __PRETTY_FUNCTION__ << '\n';
    
;

class Derived2 : public Base

public:
    void Foo()
    
        std::cout << __PRETTY_FUNCTION__ << '\n';
    

    void Bar()
    
        std::cout << __PRETTY_FUNCTION__ << '\n';
    
;

class OtherClass

public:
    Base* obj;
    void (Base::*method)();

    void Add( Base* _obj, void (Base::*_method)() )
    
        obj = _obj;
        method = _method;
    

    void Run()
    
        (obj->*method)();
    
;

int main()

    Derived1 d1;
    Derived2 d2;

    OtherClass other;

    other.Add( &d1, &Base::Foo );
    other.Run();

    other.Add( &d2, &Base::Bar);
    other.Run();

输出

virtual void Derived1::Foo()
virtual void Derived2::Bar()

【讨论】:

以上是关于C++ - 基类指针,方法指针,指派生类,方法?的主要内容,如果未能解决你的问题,请参考以下文章

C ++中派生类的相等性测试[重复]

C++中派生类的构造函数怎么显式调用基类构造函数?

c ++:将指针传递给基类时访问派生类方法?

C++:深度复制基类指针

如何从指向基类类型的指针调用派生类函数(C++)

通过基类指针C++访问派生类的成员