C++ C++;虚常数函数
给出以下代码片段C++ C++;虚常数函数,c++,C++,给出以下代码片段 class Base { public: virtual void eval() const { std::cout<<"Base Const Eval\n"; } }; class Derived:public Base { public: void eval() { std::cout<<"Derived Non-Const Eval\n"; } }; int mai
class Base
{
public:
virtual void eval() const
{
std::cout<<"Base Const Eval\n";
}
};
class Derived:public Base
{
public:
void eval()
{
std::cout<<"Derived Non-Const Eval\n";
}
};
int main()
{
Derived d;
Base* pB=&d;
pB->eval(); //This will call the Base eval()
return 0;
}
类基
{
公众:
虚拟void eval()常量
{
std::cout这是因为一个声明为常量,另一个声明为非常量。一个函数被另一个隐藏。派生中的函数隐藏在基中,因为它们具有相同的名称,而不是相同的函数
Base::eval() const;
Derived::eval(); //No const.
我的编译器在这里给出了一个警告,你的编译器呢?在你的派生的类中,eval的原型与Base
中的虚拟函数的原型不匹配。因此它不会覆盖虚拟函数
Base::eval() const;
Derived::eval(); //No const.
如果为派生::eval()
添加常量,则应获得虚拟行为。常量是函数签名的一部分。为了重写函数,重写必须与基本版本具有完全相同的签名-在这种情况下,它没有
考虑到调用代码不需要知道任何关于派生的-它是在基上调用常量函数。您不会期望该调用在一个可能改变类内容的非常量函数中结束
$10.3/2-“如果是虚拟会员功能
vf在基类和
派生类派生、直接派生或直接派生的类
间接地从基地,一个成员
具有相同名称的函数vf,
参数类型列表(8.3.5),
cv资格认证和REF资格认证(或
缺少与Base::vf相同的
声明,然后派生::vf也是
虚拟的(无论是否如此)
声明)并且它覆盖111
Base::vf。“
111)具有相同名称但
不同的参数列表(第13条)
因为虚拟函数不是
必须是虚拟的,而不是虚拟的
重写。使用虚拟
声明中的说明符
覆盖功能是合法的,但是
冗余(语义为空)。
访问控制(第11条)不适用
在确定覆盖时考虑
另一方面,请注意,它没有讨论访问规范。因此,被重写函数的基类和派生类访问规范可能不同
这意味着派生::eval不会覆盖Base::eval,因为它们的简历资格不同。您可以在脑海中翻译:
virtual void Base::eval() const;
void Derived::eval() ;
到
通过检查第二个与第一个签名的匹配程度。在C++0x中,使用base\u check
和override
关键字在编译时可以检测到这种情况:
属性上的[[base_check]]属性
类/结构表示任何隐式
压倒一切将导致
编译器错误。必须删除任何重写
显式标记为
[[override]]属性
最有可能(不太清楚语法):
好奇:什么编译器?什么警告选项?如果你打开警告,大多数编译器都会。
class Derived [[base_check]] : public Base {
virtual void eval [[override]] () {
....
}
};