如何让基类继承函数返回派生类自身指针以支持链式调用
解决链式调用中基类函数返回派生类指针的最优方案
针对你遇到的基类函数返回基类指针导致链式调用中断的问题,**CRTP(奇异递归模板模式)**是最适合的解决方案,无需在每个派生类中重写基类函数,完美契合继承的复用初衷。
核心思路
通过让基类成为模板类,将派生类作为模板参数传入基类,在基类的成员函数中把this指针安全转换为派生类指针返回,这样所有继承该基类的派生类,调用基类函数时都会返回自身类型的指针,自然支持连续的链式调用。
实现代码
#include <iostream> // 基于CRTP的基类,模板参数指定派生类类型 template<typename Derived> class Base { public: Derived* CommonFunc() { std::cout << "Common function part of Base and all derived classes" << std::endl; // 编译期安全转换为派生类指针 return static_cast<Derived*>(this); } // 新增基类公共函数无需修改派生类 Derived* AnotherCommonFunc() { std::cout << "Another common function from Base" << std::endl; return static_cast<Derived*>(this); } }; // 派生类继承时传入自身作为模板参数 class Foo : public Base<Foo> { public: Foo* UniqueFunc() { std::cout << "Unique function of the Foo class" << std::endl; return this; } }; // 另一个派生类示例 class Bar : public Base<Bar> { public: Bar* BarUniqueFunc() { std::cout << "Unique function of the Bar class" << std::endl; return this; } }; int main() { Foo* exampleFoo = new Foo(); // 链式调用不再中断,可自由混合基类和派生类函数 exampleFoo->UniqueFunc()->CommonFunc()->AnotherCommonFunc()->UniqueFunc(); std::cout << "-------------------------" << std::endl; Bar* exampleBar = new Bar(); exampleBar->BarUniqueFunc()->CommonFunc()->BarUniqueFunc(); delete exampleFoo; delete exampleBar; return 0; }
代码说明
- CRTP模板基类:基类
Base通过模板参数Derived感知派生类类型,成员函数返回Derived*,利用static_cast完成类型转换——由于派生类确实继承自Base<Derived>,这个转换在编译期是安全的。 - 派生类实现:派生类只需继承
Base<自身类名>,无需重写任何基类函数,自有函数依然返回自身指针保持链式调用。 - 扩展性:新增基类公共函数时,所有派生类自动获得返回自身指针的版本,完全不需要修改派生类代码,彻底解决原方案的维护痛点。
对比原虚函数方案的优势
- 维护成本:原方案基类新增1个函数,15个派生类都要重写;CRTP方案只需修改基类一次,派生类无额外代码。
- 性能:CRTP是编译期静态多态,没有虚函数表的运行时开销,效率更高。
- 简洁性:避免了大量重复的重写代码,代码结构更清晰。
内容的提问来源于stack exchange,提问作者CreeperCrafter979
相关产品推荐
相关产品推荐

