[当我用const参数而不是非const参数编写覆盖函数时,我认为编译器将报告错误,因为基本函数具有非const参数,但编译成功。为什么?
我的代码:
#include <iostream>
class A
{
public:
virtual uint64_t cal(uint64_t value)
{
std::cout << value << std::endl;
return value;
}
};
class B : public A
{
public:
uint64_t cal(const uint64_t value) override;
};
uint64_t B::cal(const uint64_t value)
{
std::cout << value + 1 << std::endl;
return (value+1);
}
int main()
{
B b;
b.cal(1);
return 0;
}
为什么?
因为在声明中将忽略函数参数的顶级const限定词。
uint64_t cal(uint64_t value);
和
uint64_t cal(const uint64_t value);
声明完全相同的函数类型。cal
是获取uint64_t
并返回uint64_t
的函数。const
限定符对于调用代码没有区别,因为value
始终是传入参数的copy。
唯一的区别是在函数主体中,const
限定词将阻止您修改参数。但这是一个实现细节。这种差异甚至可能引发编码风格问题。例如参见
uint64_t cal(uint64_t)
和uint64_t cal(const uint64_t)
被视为相同的function type。(重点是我的)
参数列表中每个功能参数的类型根据以下规则确定:4)
顶级cv限定词从参数类型中删除(此调整仅影响函数类型,但不修改参数的属性:
int f(const int p, decltype(p)*);
和int f(int, const int*);
声明相同功能)
const
参数不是函数签名的一部分。重载的唯一要求是签名必须匹配。#include <type_traits>
int main()
{
static_assert(std::is_same_v<int(int), int(const int)>);
}
Compiles fine