本文介绍了使用基类函数指针访问派生类成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的项目中使用函数指针,面对问题,创建一个测试用例来显示它...下面代码失败与下面的错误MSVC2005(简单的话,我想访问dervied类函数通过基类函数指针)



  class ClassA {
public:
virtual void foo()
{
printf(Foo Parent);
}
};

typedef void(ClassA :: * ClassAFoo)();

class ClassB:public ClassA {
public:
virtual void foo()
{
printf(Foo Derived);
}
};

int main(){
ClassAFoo fPtr;
fPtr =& ClassB :: foo;
}

我的问题是


  1. 是C ++的行为,我不能通过基类函数指针或其编译器错误访问派生类函数?

  2. 我一直在玩上面的case ,如果我注释掉 ClassB :: foo ,这段代码编译正常,没有任何进一步的修改,为什么这样,应该不 fPtr =& ClassB :: foo; 再次导致编译时错误?


解决方案

ol>

  • 这是正确的行为。以这种方式考虑: ClassB 的所有实例都具有成员 ClassA :: foo ,但不是所有 ClassA 有成员 ClassB :: foo ;只有那些实际是 ClassB 实例的基类子对象的 ClassA 实例才有它。因此,将 ClassB :: foo 分配到 ClassAFoo ,然后使用 ClassAFoo 结合纯 ClassA 对象将试图调用不存在的函数。


  • 如果从 ClassB 中删除​​ foo ,表达式 ClassB :: foo acutally是指在 ClassB 中继承的 ClassA :: foo ,因此没有问题。


  • 要详细说明1. further:指向成员的指针实际上与正常指针相反。使用正常指针,可以将 ClassB * 分配到 ClassA * 中(因为类B 也是 ClassA 的实例,但反之亦然。使用成员指针,可以将 ClassA :: * 分配到 ClassB :: * (因为 ClassB 包含 ClassA 的所有成员,但反之不行。


    I am using function pointer in my project, facing problem, created a test case to show it... below code fail with below error on MSVC2005 (in simple words i want to access dervied class function through base class function pointer)

    class ClassA {
     public:
        virtual void foo()
        {
           printf("Foo Parent");
        }
    };
    
    typedef void (ClassA::*ClassAFoo)();
    
    class ClassB : public ClassA {
     public:
        virtual void foo()
        {
            printf("Foo Derived");
        }
    };
    
    int main() {
        ClassAFoo fPtr;
        fPtr = &ClassB::foo;
    }
    

    My questions are

    1. Is it C++ behavior that I cant access derived class function through a base class function pointer or its a compiler bug?
    2. I have been playing with above case, if i comment out ClassB::foo, this code compile fine, without any further modification, Why is this so, should not fPtr = &ClassB::foo; again result in compile time error?
    解决方案
    1. It's correct behaviour. Think of it this way: all instances of ClassB have the member ClassA::foo, but not all instances of ClassA have the member ClassB::foo; only those instances of ClassA which are actually the base class subobject of a ClassB instance have it. Therefore, assigning ClassB::foo into ClassAFoo and then using ClassAFoo in combination with a "pure" ClassA object would try to call a nonexistent function.

    2. If you remove foo from ClassB, the expression ClassB::foo acutally refers to ClassA::foo which is inherited in ClassB, so there's no problem there.

    To elaborate on 1. further: pointers to members actually work the opposite way to normal pointers. With a normal pointer, you can assign ClassB* into ClassA* (because all instances of ClassB are also instances of ClassA), but not vice versa. With member pointers, you can assign ClassA::* into ClassB::* (because ClassB contains all the members of ClassA), but not vice versa.

    这篇关于使用基类函数指针访问派生类成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    07-08 17:48