问题标签 [virtual-inheritance]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - C ++:继承重载的非虚拟方法和同名的虚拟方法会导致问题
我正在尝试将两个具有不同参数列表的同名方法继承到派生类。其中一个是虚拟的并在派生类中被覆盖,另一个是非虚拟的。这样做,我在尝试从派生类对象访问基类的非虚拟方法时遇到编译错误。
这是代码片段
这会产生以下编译错误:
错误:没有匹配函数调用'Deriv::f()'<br /> 注意:候选者是:virtual void Deriv::f(int)
我不是 C++ 方面的专家,但直到现在我认为成员方法可以通过它们的签名完全区分的假设是正确的。因此,非虚拟方法 Base::f() 不应被覆盖并应保持可访问性。我错了吗?
以下是一些有趣的/附加的评论:
- - 重写方法 Deriv::f(int arg) 也可以是非虚拟的;错误以任何一种方式发生
- 错误消失/可以规避......
- ...通过将 Deriv 对象转换为 Base 类
...当不覆盖 Deriv 中的 Base::f(int arg) 时
...通过添加命令“Base::f;” 到 Deriv 的公共部分
所以,既然我已经知道如何避免这个编译错误,我主要感兴趣的是为什么会发生这个错误!
c++ - 在复杂的多重继承层次结构中,“virtual”关键字在哪里是必需的?
我了解 C++ 虚拟继承的基础知识。但是,我对在哪里需要使用virtual
具有复杂类层次结构的关键字感到困惑。例如,假设我有以下类:
如果我想确保没有任何类在任何子类中出现多次,则需要标记哪些基类virtual
?他们都是?或者仅在那些直接从可能具有多个实例的类(即 B、C、D、E 和 F;以及 G 和 H)派生的类上使用它就足够了(但仅与基类 E 一起使用,而不是与基类 D 和 F))?
c++ - 基类列表是指示虚拟继承的正确位置吗?
我从未见过用作虚拟和非虚拟基础的类(即,如果某个类打算成为祖先,那么我们通常会提前知道继承的类型——虚拟或非虚拟)。
所以我认为在 C++ 中有一个容易出错的自由来专门化基类列表中的“虚拟”继承。最好将基类本身指定为“虚拟”
或者也许我错了?
如果不是,任何人都可以描述一些技术来防止这种“虚拟”类的意外非虚拟继承吗?
或者在即将到来的 c++ 标准中有一些观点?
(对不起,如果重复)
一些例子
1) ReferenceCounted 类作为一些基于引用计数的智能指针可以指向的所有类的基础。我们需要防止此基本实例(和引用计数器)的重复。除了优化之外,没有理由将此类用作非虚拟基础。
2)接口的层次结构和相应的实现层次结构(在这种情况下,接口层次结构必须是“虚拟的”)
我怀疑在许多情况下,非虚拟继承不是概念上的需要,它仅用于减少虚拟继承开销(有时用于将 static_cast<> 用于驱动的能力:)
请注意,Java 仅对接口使用虚拟(就 c++ 而言)继承,而且我不知道有任何抱怨这种语言缺乏“非虚拟”(它本质上是比 c++ 表达力差的语言,但这个“特性”不是它的主要过错 :)。
c++ - 调用虚拟基类的重载构造函数
是否有一种(实用的)方法可以绕过正常(虚拟)构造函数调用顺序?
例子:
输出:
调用 A()
调用 B(int)
调用 C(int)
调用 D(int)
我想要的是这样的:
调用 A(int)
调用 B(int)
调用 C(int)
调用 D(int)
如您所见,其中涉及到虚拟继承,这导致D的构造函数首先调用A的构造函数,但是由于没有提供参数,所以它调用了A()。有需要初始化的const int i ,所以我遇到了问题。
我想做的是隐藏 C 的继承细节,这就是为什么我正在寻找一种方法来避免在 D(以及每个派生的)构造函数的初始化列表中调用 A(i)。[编辑] 在这种特定情况下,我可以假设只有 C 的非虚拟单继承子类(因为 D 是一个)。[/编辑]
[编辑]
虚拟基类在初始化任何非虚拟基类之前进行初始化,因此只有最派生的类才能初始化虚拟基类。——詹姆斯·麦克内利斯
这正是重点,我不希望最派生类调用虚拟基类构造函数。 [/编辑]
考虑以下情况(上面的代码示例中没有表示):
我明白为什么在实例化 C 时 C 必须调用 A 的 ctor(歧义),但为什么 D 在实例化 D 时必须调用它?
c++ - C++ 无法通过虚拟基 A 从基 A 转换为派生类型 B
我有三个班级:
尝试从 A* 到 B* 的静态转换我收到以下错误:
c++ - C++ 虚拟继承和类型转换/复制构造函数混淆
我有以下代码:
令我惊讶的是 B(const A& a) 没有被调用。这是为什么?
c++ - MSVC9.0的bug还是对虚拟继承的误解和朋友?
考虑以下代码:
MSVC9.0(Visual Studio 2008 的 C++ 编译器)确实生成了默认构造函数,但无法为 C 生成复制和赋值运算符,尽管 C 是 A 的朋友。这是预期的行为还是 Microsoft 的错误?我认为是后者,如果我是对的,任何人都可以指出一篇文章/论坛/...讨论这个问题或微软对这个错误做出反应的地方。先感谢您。
PS顺便说一句,如果将两个私有继承都更改为受保护,则一切正常
PPS 我需要一个证明,上面的代码是合法的还是非法的。据我了解,确实打算不能派生具有虚拟私有基础的类。但他们似乎错过了朋友部分。所以......就这样,我的第一个赏金:)
c++ - 虚拟继承不会破坏静态组合?
在过去的 5 年里,我一直在假设虚拟继承会破坏静态组合。
但现在我发现,仍然保持静态组合,只是有关正确实例位置的附加信息。这是正确的吗?
c++ - 如何确保虚拟基类上的赋值运算符只被调用一次?
我在典型的菱形问题中使用虚拟继承:
我在每个类中都实现了一个名为“deep_copy_from”的方法(但它也可以是赋值运算符=())。该方法应该复制类自己的属性,并将副本传播到上面的类。
问题是 A::deep_copy_from 方法在我深度复制 D 实例时被调用了两次(它应该只被调用一次,因为 A 只有一个“版本”)。确保它只被调用一次的最佳方法是什么?
(B::deep_copy_from 和 C::deep_copy_from 应该继续以相同的方式工作)。
这是一个示例代码:
这是当前的输出:
更新:
现在的版本是:
输出是:
我能得到比这更好的吗?(即,更自动)
c++ - “最派生类的ctor需要直接调用虚基类的ctor”这句话的原文在哪里?
当我学习如何在 C++ 中实现 final 类时,我发现了这样一个语句:
但是,我在 C++ 标准中找不到该语句的原件。(N3126)
谁能告诉我确切的页码?
提前致谢。