如何在C++中获取函数调用者的类型?
在C++中获取函数调用者类型的可行方案
嘿,我太懂这种“明明被说不推荐但确实适配自己场景”的感受了——虽然关于这个问题的讨论已经不少,给新手的建议大多是直接喊**“别这么做,这属于不良编程习惯”**,但如果这个方案刚好契合你的需求,那它就是合适的选择。
你的核心需求是:在C++中获取函数调用者的类型,用于typeid(CALLER)操作,结合你提到的场景——有一个AnalyzedObject作为多个多态Evaluator的评估对象,我来给你几个针对性的可行思路:
方案一:模板推导+调用者传递自身类型(最安全推荐)
这是符合C++标准、无未定义行为的最优解,只需要调用者稍微配合传递一下自身指针:
#include <typeinfo> #include <iostream> class AnalyzedObject { public: // 模板方法,自动推导调用者类型 template<typename CallerType> void processEvaluation(CallerType* caller) { // 直接通过typeid获取调用者的实际类型 const std::type_info& callerType = typeid(CallerType); std::cout << "当前调用者类型:" << callerType.name() << std::endl; // 结合你的场景,比如判断调用者是否为特定Evaluator子类 if (callerType == typeid(SpecificEvaluator)) { // 针对SpecificEvaluator的专属逻辑 std::cout << "处理SpecificEvaluator的评估请求" << std::endl; } else if (callerType == typeid(AnotherEvaluator)) { // 其他Evaluator的逻辑 std::cout << "处理AnotherEvaluator的评估请求" << std::endl; } } }; // 多态Evaluator基类 class BaseEvaluator { public: virtual void evaluate(AnalyzedObject& obj) = 0; virtual ~BaseEvaluator() = default; }; // 具体Evaluator子类 class SpecificEvaluator : public BaseEvaluator { public: void evaluate(AnalyzedObject& obj) override { // 传递this指针,模板自动推导当前类型 obj.processEvaluation(this); } }; class AnotherEvaluator : public BaseEvaluator { public: void evaluate(AnalyzedObject& obj) override { obj.processEvaluation(this); } }; // 测试代码 int main() { AnalyzedObject obj; SpecificEvaluator eval1; AnotherEvaluator eval2; eval1.evaluate(obj); eval2.evaluate(obj); return 0; }
这个方案的优势在于:
- 完全符合标准,跨编译器兼容
- 哪怕通过基类指针调用(比如
BaseEvaluator* ptr = new SpecificEvaluator();),传递this依然能准确获取实际子类的类型 - 代码可读性高,耦合度可控(如果后续新增Evaluator,只需要在
processEvaluation里新增判断逻辑即可)
方案二:宏辅助传递类型(应急/简化调用)
如果你想让调用者的代码更简洁,可以用宏来封装类型传递的逻辑,本质和方案一类似,但减少了模板代码的显性书写:
#include <typeinfo> #include <iostream> class AnalyzedObject { public: void processEvaluation(const std::type_info& callerType) { std::cout << "当前调用者类型:" << callerType.name() << std::endl; // 同样的类型判断逻辑 if (callerType == typeid(SpecificEvaluator)) { std::cout << "处理SpecificEvaluator的评估请求" << std::endl; } } }; // 定义宏,自动获取调用者类型并传递 #define EVALUATE(obj) obj.processEvaluation(typeid(*this)) // Evaluator类定义同方案一 class SpecificEvaluator : public BaseEvaluator { public: void evaluate(AnalyzedObject& obj) override { // 直接调用宏即可 EVALUATE(obj); } };
不过这个方案要注意:宏的可读性稍差,而且如果在非成员函数中调用会报错(因为this不存在),所以只适合你的类成员函数调用场景。
为什么大家说这是不良编程习惯?
最后也解释一下为啥很多开发者不推荐这种做法:它会让AnalyzedObject和调用它的Evaluator类型产生耦合,违反了依赖倒置原则——原本AnalyzedObject应该只关心自己的逻辑,现在却要依赖调用者的类型。如果后续Evaluator的子类频繁新增或修改,AnalyzedObject的逻辑也需要跟着改动,维护成本会变高。
但如果你的场景中,Evaluator的类型是相对稳定的,或者这种类型判断是业务逻辑的核心需求,那这个方案完全是合理的,不用被“不良习惯”的说法束缚。
内容的提问来源于stack exchange,提问作者Szał Pał
相关产品推荐
相关产品推荐

