问题描述
我在我的项目中使用函数指针,面对问题,创建一个测试用例来显示它...下面代码失败与下面的错误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;
}
我的问题是
- 是C ++的行为,我不能通过基类函数指针或其编译器错误访问派生类函数?
- 我一直在玩上面的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
- Is it C++ behavior that I cant access derived class function through a base class function pointer or its a compiler bug?
- 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 notfPtr = &ClassB::foo;
again result in compile time error?
It's correct behaviour. Think of it this way: all instances of
ClassB
have the memberClassA::foo
, but not all instances ofClassA
have the memberClassB::foo
; only those instances ofClassA
which are actually the base class subobject of aClassB
instance have it. Therefore, assigningClassB::foo
intoClassAFoo
and then usingClassAFoo
in combination with a "pure"ClassA
object would try to call a nonexistent function.If you remove
foo
fromClassB
, the expressionClassB::foo
acutally refers toClassA::foo
which is inherited inClassB
, 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.
这篇关于使用基类函数指针访问派生类成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!