热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用声明作为覆盖

如何解决《使用声明作为覆盖》经验,为你挑选了1个好方法。

我们在标准中有以下简单(并稍加修改以添加main和输出)示例:

struct A {
    virtual void f()
    {
        cout <<"A\n";
    }
};

struct B : virtual A {
    virtual void f()
    {
        cout <<"B\n";
    }
};

struct C : B, virtual A {
    using A::f;
};

int main()
{
    C c;
    c.f();              // calls B?::?f, the final overrider
    c.C::f();
    return 0;
}

从中我们可以得出一个using A::f不存在重写的结论.但标准中的措辞是什么意思呢?以下是C++ 17草案([class.virtual] p2)中最终覆盖的措辞:

<...>类对象S的虚拟成员函数C :: vf是最终覆盖,除非其中S是基类子对象(如果有)的最派生类(4.5)声明或继承覆盖的另一个成员函数vf.在派生类,如果一个基类子对象的虚拟成员函数具有一个以上的最终超控器程序是非法的构造.

我无法找到"覆盖"实际意味着什么.如果没有定义并且我们将任何声明视为重载,那么我们应该将using声明视为重载,因为[namespace.udecl] p2说:

每个using声明都是声明和成员声明,​​因此可以在类定义中使用.

我理解标准使用声明的意图是不引入覆盖,但有人能指出我在Standardese中的实际引用吗?这是第一部分,现在是第二部分


请考虑以下代码:

#include 
#include 

using std::cout;

class A {
public:
    virtual void print() const {
        cout <<"from A" <

如果using声明没有引入覆盖,那么我们有2个最终覆盖D,因此 - 由于的未定义行为

在派生类中,如果基类子对象的虚拟成员函数具有多个最终覆盖,则程序是格式错误的.

对?



1> StoryTeller ..:

就声明性区域而言,使用声明虽然确实是声明,但它不是函数声明.我们可以看到它用语法指定:

[dcl.dcl]

1声明通常指定如何解释名称.声明具有形式

declaration:
  block-declaration
  nodeclspec-function-declaration
  function-definition
  template-declaration
  deduction-guide
  explicit-instantiation
  explicit-specialization
  linkage-specification
  namespace-definition
  empty-declaration
  attribute-declaration

block-declaration:
  simple-declaration
  asm-definition
  namespace-alias-definition
  using-declaration
  using-directive
  static_assert-declaration
  alias-declaration
  opaque-enum-declaration

nodeclspec-function-declaration:
  attribute-specifier-seq declarator ;

并且在某种程度上是语义上的.由于以下段落详细说明了如何从基类引入成员函数的using声明与派生类中的成员函数声明不同.

[namespace.udecl]

15当using-declarator将基类的声明带入派生类时,派生类中的成员函数和成员函数模板覆盖和/或隐藏具有相同名称的成员函数和成员函数模板,parameter-type-list,cv - 基类中的-qualification和ref-qualifier(如果有)(而不是冲突).这些隐藏或重写的声明被排除在using-declarator引入的声明集之外.

16出于重载解析的目的,using-declaration引入派生类的函数被视为派生类的成员.特别是,隐式this参数应被视为指向派生类而不是基类的指针.这对函数的类型没有影响,并且在所有其他方面,函数仍然是基类的成员.

考虑到这一点,如果考虑到第一段的开头,你引用:

[class.virtual]

2如果虚拟成员函数vf在类Base和Derived中直接或间接派生的类中声明,则具有相同名称的成员函数vf,parameter-type-list,cv-qualification和ref-qualifier(或如果没有 Base?::?vf声明,那么Derived?::?vf它也是虚拟的(无论是否如此声明)并且它会覆盖Base?::?vf.为方便起见,我们说任何虚函数都会覆盖自身.

我们可以看到它是一个虚函数声明,可以为基类中的虚函数引入一个覆盖.由于使用声明不是函数声明,因此它不符合条件.

目前的措辞部分来自CWG缺陷608.其目的是澄清该报告中有问题的解释,并将声明与虚函数覆盖的概念分离.


关于你的第二个问题,引用中重要的是"基类子对象 ".您的代码示例中有两个 A子对象D(该示例中的继承不是虚拟的).而每一个在拥有自己的最终置换器BC分别.所以程序不是格式错误,无论是否声明了另一个覆盖者D.

您关注的段落适用于虚拟继承的情况.如果BC拥有一个虚拟A基础,并D从两者继承而没有覆盖print,那么该程序将是不正确的.并且using C::print由于上述原因,使用声明不会使其形成良好.


推荐阅读
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
author-avatar
AA一缕阳光
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有