更新时间:2023-02-14 22:43:14
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)
error C2440: '=' : cannot convert from 'void (__thiscall ClassB::* )(void)' to 'ClassAFoo'
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
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?
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.
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.