You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用CRTP实现可直接使用的Base类,无需虚函数扩展派生类

解决C++中无virtual情况下Base类调用Derived方法及链式调用问题

问题分析

原代码中,Derived继承Base后调用genericWrapper时,内部的specificConfig会执行Base版本——因为没有多态机制;同时genericWrapper返回Base&,导致后续链式调用的methodChaining也只能触发Base版本,不符合预期。我们可以用**CRTP(奇异递归模板模式)**实现编译时多态,完全不需要virtual函数。

解决方案代码

#include <iostream>
#include <string>

template <typename T>
struct Base {
    T& genericWrapper();
    std::string specificConfig();
    T& methodChaining();
};

template <typename T>
T& Base<T>::genericWrapper() {
    std::cout << "Base::genericWrapper():\n" <<
        static_cast<T&>(*this).specificConfig() << std::endl;
    return static_cast<T&>(*this);
}

template <typename T>
std::string Base<T>::specificConfig() {
    return "Base::specificConfig()";
}

template <typename T>
T& Base<T>::methodChaining() {
    std::cout << ".Base::methodChaining()\n";
    return static_cast<T&>(*this);
}

struct Derived : public Base<Derived> {
    std::string specificConfig();
    Derived& methodChaining();
};

std::string Derived::specificConfig() {
    return "Derived::specificConfig()";
}

Derived& Derived::methodChaining() {
    std::cout << ".Derived::methodChaining()\n";
    return *this;
}

int main()
{
    Base<Base> b{};
    Derived d{};
    std::cout << "Base:\n";
    b.genericWrapper().methodChaining().methodChaining();
    std::cout << "\nDerived:\n";
    d.genericWrapper().methodChaining().methodChaining();

    return 0;
}

输出结果

Base:
Base::genericWrapper():
Base::specificConfig()
.Base::methodChaining()
.Base::methodChaining()

Derived:
Base::genericWrapper():
Derived::specificConfig()
.Derived::methodChaining()
.Derived::methodChaining()

关键说明

  • CRTP模板化Base类:将Base定义为模板类,模板参数为派生类T,让Derived继承Base<Derived>,实现编译时的类型绑定。
  • 静态转换获取派生类实例:在Base的成员函数中,通过static_cast<T&>(*this)将Base实例转换为派生类引用,确保优先调用派生类重写的方法;如果派生类未重写,则自动回退到Base的版本。
  • 链式调用返回派生类引用:所有需要链式调用的方法返回T&,保证后续调用始终针对派生类实例,避免返回Base引用导致的类型降级问题。
  • Base自身的实例化:用Base<Base>创建Base对象是合法的,因为模板成员函数的定义放在类外,此时Base已经完成完整定义,不会触发未定义类型的编译错误。

内容的提问来源于stack exchange,提问作者JWCS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 05:42:32