为什么你不能在派生类中获得指向override方法的指针?
以下是一个例子:
基类
#ifndef BASE_H
#define BASE_H
class Base
{
typedef void (Base::*BasePointer)( void );
public:
Base(){}
protected:
virtual void FunFunction( void )
{
}
BasePointer pointer;
};
#endif /* BASE_H */
派生类
#ifndef DERIVED_H
#define DERIVED_H
#include "Base.h"
class Derived : public Base
{
public:
Derived()
{
pointer = &Base::FunFunction;
}
protected:
// Overrides base function
void FunFunction( void )
{
}
};
#endif /* DERIVED_H */
Derived类中的构造函数尝试将继承的指针值设置为等于覆盖方法FunFunction
的地址。但产生的错误是"错误:' FunFunction'是' Base'"的受保护成员。更改FunFunction对公共的访问权限可以解决此问题。然而FunFucntion不能公开。
为什么FunFunction
受保护会出现问题?
有什么方法可以获得这种理想的功能吗?
修改
解决方案是否可以将this
转换为Base类,然后获取函数的地址?像&(((Base*)this)::FunFunction);
之类的东西虽然那个例子不起作用。
答案 0 :(得分:0)
您只能通过Base
访问Derived
受保护的成员。
至少在VS2012中从&Derived::Base::FunFunction
yilds调用Derived
没有错误。所以下面的代码将起作用:
class Base
{
public:
typedef void (Base::*BasePointer)( void );
Base()
{
pointer2 = &Base::FunFunction;
}
protected:
virtual void FunFunction( void )
{
std::cout << "Base::FunFunction\n";
}
BasePointer pointer;
BasePointer pointer2;
};
class Derived : public Base
{
public:
Derived()
{
pointer = &Derived::Base::FunFunction;
}
void RunBaseHiddenMethod()
{
(this->*(pointer))();
}
void RunFunFunction()
{
FunFunction();
}
protected:
// Overrides base function
virtual void FunFunction( void ) override
{
std::cout << "Derived::FunFunction\n";
}
};
int main (int argc, char *argv[])
{
Derived d;
d.RunBaseHiddenMethod();
d.RunFunFunction();
return 0;
}
结果:
Derived::FunFunction
Derived::FunFunction
编辑:但是(正如你所看到的)它对你没有帮助! 在调试器中:
(((Base )(&amp;(d))))。指针0x00be14ab {ConsoleApplication1.exe![thunk]:Base ::`vcall&#39; {0,{flat} }&#39; }&#39;}
(((Base )(&amp;(d))))。pointer2 0x00be14ab {ConsoleApplication1.exe![thunk]:Base ::`vcall&#39; {0,{flat} }&#39; }&#39;}
指针只保存index
virtual
函数 - 而不是绝对地址。因此pointer==pointer2
。
BTW can
访问static
protected
成员函数:
class Base
{
public:
typedef void (BasePointer)(void );
Base(){}
protected:
static void FunFunction( void )
{
std::cout << "Base::FunFunction\n";
}
BasePointer* pointer;
};
class Derived : public Base
{
public:
Derived()
{
pointer = &Base::FunFunction; //OK
}
void RunBaseMethod()
{
pointer();
}
};
另一个问题:为什么我们无法获得成员函数的绝对地址(如exported
地址)?很明显,编译器知道这些地址。
答案 1 :(得分:-1)
Pure C ++不允许创建指向类的成员函数的指针,除非它是静态函数。 除非您使用的是C ++ Builder,它使用Delphi的技巧来创建和管理函数指针,否则您尝试做的事情是不可能的。请记住,类的成员函数具有指向类实例的隐藏参数。
萨姆