C++虚函数重写中const形参为何被编译器忽略?
为什么派生类重写时可以省略基类虚函数参数的顶层const?
这是因为函数参数的顶层const不参与函数签名的构成,也不会影响C++的虚函数重写校验规则,具体可以拆解成以下几点:
- 顶层const与函数签名的关系
C++标准规定,函数签名仅包含函数名称、参数的类型(包括底层const,比如const int&或const int*),但顶层const(即修饰参数本身的const,比如const int a)会被视为和非const版本的参数类型完全一致。
所以基类中的virtual void set(const int a)和派生类中的void set(int a),它们的函数签名是完全匹配的——这也是编译器允许你用override关键字通过校验的核心原因。
- 重写时允许调整参数的顶层const
基类虚函数的参数const int a里的const,仅限制在基类的函数内部不能修改这个参数副本;而派生类重写时去掉const,只是允许自己的函数内部修改这个参数副本,这是完全合法的。
因为顶层const只影响函数内部对参数的操作,不会改变函数的调用方式:无论是调用基类还是派生类的set函数,传入一个int类型的参数都是可行的,所以C++允许派生类在重写时自由选择是否保留参数的顶层const。
- 和普通函数的区别
你给出的test1和test2的例子,本质是同一作用域下的函数声明:由于void test1(int a)和void test2(const int a)签名一致,如果你同时声明这两个函数会直接报重复定义错误;而test2内部修改a报错,只是因为函数内部的参数是const类型,不允许修改——这和虚函数重写的签名规则是两个独立的问题。
// 同一作用域下这样写会报错:重复定义 void test1(int a) {} void test2(const int a) {} // 与test1签名一致,编译器视为同一个函数
内容的提问来源于stack exchange,提问作者tenspd137
相关产品推荐
相关产品推荐

