如何通过CSpellData指针调用其成员函数指针_vptr?
解决成员函数指针的调用问题
核心语法错误
你当前的写法_c_spell_data->_vptr;仅获取了成员函数指针的值,并未触发函数调用。成员函数指针的调用需要严格遵循语法规则,由于运算符优先级限制,必须用括号明确绑定对象与指针:
// 基础调用语法(需先解决const冲突问题) (_c_spell_data->*(_c_spell_data->_vptr))();
const限定符冲突问题
你的代码存在关键矛盾:_c_spell_data是const CSpellData*类型(指向const对象的指针),但_vptr是指向非const成员函数的指针(void (CSpellData::*)())。const对象仅允许调用const成员函数,因此编译器会拒绝上述调用,需根据实际场景二选一解决:
场景1:回调函数无需修改对象状态
如果FireballCallback、StoneskinCallback等函数不修改CSpellData的成员变量,将它们声明为const成员函数,并同步修改指针类型:
- 更新
_vptr的定义:
// CSpellData.h中修改成员定义 void (CSpellData::* _vptr)() const;
- 调整
GetCallbackFromID的返回类型与函数签名:
void (CSpellData::* CSpellData::GetCallbackFromID(ESpellID spell_id))() const { switch (spell_id) { case ESpellID::FIREBALL: return &CSpellData::FireballCallback; case ESpellID::STONESKIN: return &CSpellData::StoneskinCallback; default: return nullptr; // 添加默认返回值,避免未定义行为 } }
- 确保回调函数本身为const:
class CSpellData { public: void FireballCallback() const; void StoneskinCallback() const; // ...其他成员 };
完成上述修改后,即可用基础语法正常调用。
场景2:回调函数需要修改对象状态
如果回调函数必须修改CSpellData的内部状态,移除_c_spell_data的const限定:
// Spell.h中修改指针类型 CSpellData* _c_spell_data;
之后使用基础调用语法即可触发回调:
(_c_spell_data->*(_c_spell_data->_vptr))();
额外建议
- 调用前建议检查指针有效性,避免空指针访问:
if (_c_spell_data && _c_spell_data->_vptr) { (_c_spell_data->*(_c_spell_data->_vptr))(); }
内容的提问来源于stack exchange,提问作者crvenkapavica
相关产品推荐
相关产品推荐

