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

C++派生类中重载函数未被调用的原因及解决方法

问题原因
  • 名字查找规则限制:基类Compare的operator()中调用compare(a, b)时,名字查找只会在基类作用域内匹配符号,编译期就会绑定到基类自己的compare模板函数,不会查找派生类作用域的同名函数。派生类的compare函数只是隐藏了基类的同名函数,对基类内部的调用不可见。
  • 无动态绑定逻辑:compare函数不是虚函数,即使派生类定义了同名重载,运行时也不会触发动态分发,基类调用的永远是自身作用域内的函数实现。
修复方案

推荐使用CRTP(奇异递归模板模式)实现编译期静态多态,无虚函数开销即可让基类调用派生类的重载实现,修改后的代码如下:

#include <stdio.h>
struct A {};

// 基类改为CRTP模板,接收派生类作为模板参数
template <typename Derived>
struct Compare {
  template <typename T> bool operator()(const T& a, const T& b) const {
    printf("from operator()\n");
    // 强转为派生类指针,调用派生类的compare实现
    return static_cast<const Derived*>(this)->compare(a, b);
  }
protected:
  // 通用比较逻辑放到protected,派生类可按需 fallback 调用
  template <typename T> 
  bool base_compare(const T& a, const T& b) const {
    printf("from base compare template \n");
    return true; 
  }
};

// 派生类继承时传入自身类型给CRTP基类
struct CompareDerived : public Compare<CompareDerived> {
  // 重载A类型的比较逻辑
  bool compare(const A& n, const A& p) const {
    printf("from derived overload\n");
    return true;
  }
  // 通用类型回退到基类实现
  template <typename T>
  bool compare(const T& a, const T& b) const {
    return base_compare(a, b);
  }
};

template <typename T, typename Comp = CompareDerived> 
bool trigger (const T& a, const T&b, const Comp& compare = Comp()) {
    return compare(a, b);
}

int main()
{
    A a1, a2;
    CompareDerived m;
    trigger<A, CompareDerived>(a1, a2, m);
    return 0;
}

修改后运行输出结果为:

from operator()
from derived overload

如果不需要支持泛型扩展,也可以在基类声明针对A类型的虚函数,派生类重写该虚函数即可实现调用,不过该方案仅支持提前约定的类型,扩展性弱于CRTP方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:54:02