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

C++类重写疑问:为何添加const后未调用Derived类虚函数

问题原因解析

核心问题出在模板参数与const结合时的类型差异,以及C++虚函数覆盖的签名匹配规则:

1. 基类的参数类型拆解

当实例化A<int*>时,基类中的virtual void some_function(const T a),这里的const T等价于const (int*),也就是**int* const a**——这个const修饰的是指针本身,意思是指针变量a的指向不可修改,但指针指向的int值可以修改。

2. 派生类的参数类型错误匹配

你最初在派生类中写的virtual void some_function(const int* a),这里的const修饰的是int,实际类型是**const int* a**——意思是指针a的指向可以修改,但指针指向的int值不可修改。

这两个参数类型完全不同,因此派生类的这个函数并没有**覆盖(override)**基类的虚函数,而是定义了一个新的独立虚函数。当用基类指针A<int*>* p调用some_function时,编译器匹配的是基类的虚函数版本,所以输出Base。

3. 移除const后成功覆盖的原因

当去掉派生类参数的const,参数类型变为int* a,此时和基类的int* const a属于等价的函数签名——因为函数参数中的顶层const(修饰参数本身的const)会被编译器忽略,编译器认为这两个函数的签名一致。因此派生类的函数成功覆盖了基类的虚函数,基类指针调用时触发多态,执行派生类的版本,输出Derived。

避坑建议

在派生类中重写虚函数时,一定要加上override关键字,比如:

class Derived : public A<int*>
{
public:
    // 加上override后,编译器会检查是否真的覆盖了基类虚函数,不匹配会直接报错
    virtual void some_function(const int* a) override;
};

这样如果参数类型不匹配,编译器会直接提示错误,避免你误以为函数被覆盖而出现预期外的行为。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:35:24