我在我的项目中使用函数指针,面临问题,创建了一个测试用例来显示它...下面的代码失败,MSVC2005上面出现以下错误(简单来说我想通过基类函数指针访问dervied类函数)
错误C2440:'=':无法转换为'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;
}
我的问题是
ClassB::foo
,这段代码编译得很好,没有任何进一步修改,为什么这样,fPtr = &ClassB::foo;
不应该再次导致编译时错误? 答案 0 :(得分:5)
这是正确的行为。可以这样考虑:ClassB
的所有实例都有成员ClassA::foo
,但并非ClassA
的所有实例都有成员ClassB::foo
;只有那些ClassA
实际上是ClassB
实例的基类子对象的实例才有它。因此,将ClassB::foo
分配到ClassAFoo
然后将ClassAFoo
与“纯”ClassA
对象结合使用会尝试调用不存在的函数。
如果您从foo
移除ClassB
,则表达式ClassB::foo
实际上是指ClassA::foo
继承的ClassB
,因此没有问题那里。
进一步阐述1.指向成员的指针实际上与普通指针的工作方式相反。使用普通指针,您可以将ClassB*
分配到ClassA*
(因为ClassB
的所有实例也是ClassA
的实例),但反之亦然。使用成员指针,您可以将ClassA::*
分配到ClassB::*
(因为ClassB
包含ClassA
的所有成员),但反之亦然。
答案 1 :(得分:3)
是的,没关系。您不能分配class A
class B
函数指针的函数指针。
你可以这样做
fPtr = &ClassA::foo;
ClassB b;
classA* a = &b;
(a->*fPtr)();
和ClassB
函数中的覆盖将被调用。
如果foo
中没有功能ClassB
,则会使用ClassA
的功能。 Live example
答案 2 :(得分:0)
首先,我不是C ++专家(我正在努力学习C ++)。如果我错了,请纠正我,这是一个实验。
作为学习成员函数指针的一部分,我还在搜索使用基本成员函数指针调用派生成员的代码示例。在完成这个线程后,我创建了一个代码示例,即使成员函数不是虚函数,也可以调用派生成员函数。
我正在使用代理人充当祈求者。我希望它对某些人有帮助。 (纠正我如果我做错了什么)
stdClass Object
(
[CustomFields] => stdClass Object
(
[c] => stdClass Object
(
[make] => Some value
)
)
[StatusWithType] => stdClass Object
(
[Status] => stdClass Object
(
[ID] => 34
)
)
)
输出:
delegate.Invoke()将调用Derived :: SimpleMethod(),输出将为" Derived :: SimpleMethod" **