指向模板类成员函数的函数指针

本文探讨了C++中模板函数指针的使用限制,并提供了一种变通方案来实现模板类成员函数指针,这对于理解和应用C++模板机制非常有用。

http://blog.youkuaiyun.com/templarzq/article/details/8047154


c++标准不支持模板函数指针,比如:

[cpp]  view plain copy
  1. template <typename Type>  
  2. typedef int (* Func) (constType& type);//提示编译错误  

不过我们可以这样写:

[cpp]  view plain copy
  1. template<typename COL_TYPE,typename RESULT_TYPE>  
  2. class CAggCalculator {  
  3. private:  
  4.     typedef bool (CAggCalculator::* AggFuncT) (CColumnSeg<COL_TYPE>& columnSeg,RESULT_TYPE& result);  
  5.   
  6.     typename CAggCalculator<COL_TYPE,RESULT_TYPE>::AggFuncT m_pAggFuncT;  
  7. .....  
  8. };  


这样我们就得到一个指向 bool xxx(CColumnSeg& columnSeg,RESULT_TYPE& result);类型的模板类成员函数了


<think>好的,我现在需要帮助用户解决如何在C++中使用typedef定义类成员函数指针的问题。用户已经提供了一些相关的引用内容,我需要仔细分析这些内容,并结合之前的知识来给出一个清晰的回答。 首先,用户的问题是关于C++中使用typedef定义类成员函数指针,特别是如何让类指针指向成员函数。根据用户提供的引用,引用[1]提到在C++中直接像C那样使用类成员函数指针会报错,因为非静态成员函数必须通过对象调用。引用[2]中的例子展示了如何声明成员函数指针,并通过具体对象来调用。引用[3]则演示了继承情况下成员函数指针的使用,以及如何通过基类和派生类指针调用不同的函数。 我需要整理这些信息,分步骤解释如何正确使用typedef来定义成员函数指针,并说明如何通过类指针调用。同时,用户之前的回答中提到了普通函数指针的typedef用法,现在需要扩展到类成员函数指针,因此需要对比两者的差异,特别是需要指出类成员函数指针必须绑定对象实例的特点。 接下来,我应该考虑用户可能的疑惑点,比如语法结构、typedef的正确写法、调用方式(使用.*或->*操作符),以及在继承中的表现。此外,用户可能需要知道如何将成员函数指针作为参数传递或存储在结构体中,这些应用场景也需要提及。 另外,需要指出常见的错误,例如忘记指定类作用域、未使用正确的调用语法等。同时,结合用户提供的例子,说明如何正确赋值和调用成员函数指针,尤其是在多态情况下的行为。 最后,生成的相关问题应该覆盖用户可能进一步探索的方向,比如多态中的应用、与普通函数指针的区别、回调机制的使用等。确保回答结构清晰,步骤分明,帮助用户逐步理解和应用相关知识。</think>### C++类成员函数指针`typedef`使用详解 #### 一、核心语法结构 成员函数指针的`typedef`定义必须包含**类作用域限定**,语法格式为: ```cpp typedef 返回类型 (类名::*类型名)(参数列表); ``` 例如定义`Student`类的无参函数指针类型: ```cpp typedef void (Student::*StuAction)(); // StuAction为类型名 ``` #### 二、完整使用流程(含对象绑定) 1. **定义函数指针类型** ```cpp class Printer { public: void printA() { cout << "A型输出" << endl; } void printB(int x) { cout << "B型输出:" << x << endl; } }; typedef void (Printer::*SimpleFunc)(); // 无参类型 typedef void (Printer::*ParamFunc)(int); // 带参类型 ``` 2. **声明变量并赋值** ```cpp Printer obj; SimpleFunc func1 = &Printer::printA; // 必须使用取地址符& ParamFunc func2 = &Printer::printB; ``` 3. **通过对象调用**(必须使用`.*`或`->*`操作符) ```cpp (obj.*func1)(); // 输出:A型输出 (obj.*func2)(100); // 输出:B型输出:100 Printer* pObj = &obj; (pObj->*func2)(200); // 输出:B型输出:200 ``` #### 三、与普通函数指针的关键差异 | 特性 | 普通函数指针 | 类成员函数指针 | |---------------------|----------------------------|-----------------------------------| | 作用域限定 | 不需要 | 必须使用`类名::*`声明[^1] | | 存储内容 | 函数地址 | 函数地址+对象偏移信息 | | 调用方式 | 直接调用 | 必须通过对象实例调用[^2] | | 内存占用 | 通常4/8字节 | 可能为12-16字节(含隐藏this指针) | #### 四、继承场景的特殊表现 ```cpp class Base { public: virtual void show() { cout << "Base" << endl; } }; class Derived : public Base { public: void show() override { cout << "Derived" << endl; } }; typedef void (Base::*ShowFunc)(); int main() { ShowFunc func = &Base::show; Derived d; (d.*func)(); // 输出Derived(多态特性仍然有效) Base* pb = &d; (pb->*func)(); // 同样输出Derived } ``` #### 五、高级应用示例 1. **作为回调函数参数** ```cpp typedef void (Worker::*Callback)(int status); class Task { public: void setCallback(Callback cb, Worker* w) { m_cb = cb; m_worker = w; } void execute() { (m_worker->*m_cb)(100); // 触发回调 } private: Callback m_cb; Worker* m_worker; }; ``` 2. **存储在容器中** ```cpp std::vector<std::pair<Printer*, SimpleFunc>> funcList; funcList.emplace_back(&obj1, &Printer::printA); funcList.emplace_back(&obj2, &Printer::printB); for(auto& item : funcList) { (item.first->*item.second)(); } ``` #### 六、常见错误排查 1. **未绑定对象导致崩溃** ```cpp SimpleFunc func = &Printer::printA; func(); // 错误!缺少对象实例 ``` 2. **作用域声明错误** ```cpp typedef void (*WrongFunc)(); // 缺少类作用域声明 ``` 3. **虚函数指针的特殊性** ```cpp typedef void (Base::*VirtualFunc)(); VirtualFunc vfunc = &Base::show; // 实际调用时仍会触发多态 ``` ### 引用说明 类成员函数指针通过`类名::*`语法实现类型绑定,调用时必须配合具体对象实例[^1][^2]。其底层实现包含隐式的`this`指针传递机制,这是与普通函数指针的本质区别[^3]。 --- ### 相关问题 1. 如何通过成员函数指针实现多态调用? 2. 成员函数指针能否转换为`void*`类型存储? 3. 模板类中的成员函数指针`typedef`如何定义?[^1][^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值