标题已经说明了一切。我不明白为什么编译器会允许这样做:
#include <iostream>
class Base
{
public:
Base() = default;
virtual ~Base() {}
virtual void set(const int a) = 0;
};
class Derived : public Base
{
public:
Derived() = default;
virtual ~Derived() {}
void set(int a) override <-------const tossed out
{
a = 2;
std::cout << "In derived set" << std::endl;
my_a = a;
}
int my_a = 0;
};
int main()
{
Derived d;
d.set(4);
}
我知道从功能上讲,
const int a
和int a
是副本 - 但为什么 const 作为签名的一部分被忽略?
编译器(正确地)对此抱怨:
void test1(int a)
{
a = 2;
}
void test2(const int a)
{
a = 2; <------ compile error
}
那么为什么重写会通过并且基本上允许我在派生类中做同样的事情?为什么
const
不是覆盖验证签名的一部分?
可能是一个愚蠢的问题 - 但我不明白为什么。
谢谢!
顶级
const
根本没有任何意义,就像此类参数的名称一样。它不是函数类型或签名的一部分。
之所以如此,是因为这样的
const
只能对特定的定义有意义。它对于调用者来说没有任何意义,因为声明是为调用者编写的。在调用站点,函数参数是否为顶级没有区别const
。
那么
virtual void set(const int a) = 0;
100% 相当于
virtual void set(int) = 0;
因为它也适用于任何其他功能。无论函数参数在声明中是否为
const
,它在定义中始终可以是顶级 const
。
例如:
void f(int); // declaration, not a definition
// definition of the same function with `a` being unmodifiable in the definition
void f(const int a) { }
或:
// declaration, not a definition; `const` ignored
void g(const int);
// definition of same function with `a` modifiable
void g(int a) { }
因此,在确定虚函数覆盖时,顶级
const
也会被忽略。