问题标签 [diamond-problem]
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++ 中的虚拟基类
我对虚拟基类有疑问。为了解决多重继承中的“可怕的死亡钻石”/歧义问题,引入了虚拟基类。
声明virtual
中未使用关键字时会发生什么。class C
你能详细解释一下吗?
c++ - 从具有虚函数的多个继承类派生的类的大小
考虑下面的钻石场景:
- Base的大小为8 [ x(4) + vptr(4) (来自虚拟析构函数) ]
- Derived1的大小为16 [ x(4) + y(4) + vptr(4) (来自虚拟析构函数) + vptr(4) (来自虚拟继承) ]
- Derived2的大小为16 [ x(4) + z(4) + vptr(4) (来自虚拟析构函数) + vptr(4) (来自虚拟继承) ]
- Derived3的大小为28 [ x(4) + y(4) + z(4) + t(4) + vptr(4)(来自虚拟析构函数)+ 2 倍 vptr(4)(来自 Derived1 和 Derived2 的虚拟继承) ]
现在,如果我添加另一个派生自Derived 3的类Derived4,
它的大小是32(我假设它是Derived3 + s 的大小)。
我想知道Derived4内部是否没有虚拟指针?
如果我采用普通的类层次结构(没有菱形结构),那么如果基类具有虚函数,那么所有派生类都有 vptrs。那么,为什么不在这种情况下呢?
我正在使用 GNU GCC 编译器编译 codeBlocks 12.11 中的代码。
c++ - 菱形的范围
我想做一个函数来检查一个点是否在菱形范围内,
我最终得到一个矩形范围如何使这个范围成为菱形?,其中位置为中心,高度=120 宽度=200
c++ - 避免钻石继承
我有一堂课A
。
classesB
和C
是从 class 派生的接口A
。
现在我必须实现类D
和E
两者。B
C
然后是一些类:FDB
, GDC
, HEC
, IEB
, JDB
, KDC
, LEB
, MEC
(而DB
这些DC
类的名称末尾的 and 表示该类使用D
and作为, and for , and for等B
的结尾。DB
D
C
DC
E
B
EB
所以:
但后来我有一个钻石遗产,我不想要它。
有人可以建议另一种设计吗?
任何帮助表示赞赏!
java - 如何在 Java 中使用单应方法实现接口?
在英语中,同形异义词对是拼写相同但含义不同的两个单词。
在软件工程中,一对单应方法是指名称相同但需求不同的两种方法。让我们看一个人为的例子,以使问题尽可能清楚:
我该如何实施I12
?C#有办法做到这一点,但 Java 没有。所以唯一的办法就是破解。如何最可靠地使用反射/字节码技巧/等来完成它(即它不必是一个完美的解决方案,我只想要一个效果最好的解决方案)?
请注意,我无法合法进行逆向工程的一些现有的封闭源大量遗留代码需要一个类型参数,并将两者I12
委托给具有作为参数的代码和具有作为参数的代码。所以基本上我需要创建一个知道它何时应该作为以及何时应该作为的实例,我相信这可以通过在直接调用者的运行时查看字节码来完成。我们可以假设调用者没有使用反射,因为这是简单的代码。问题是作者没想到Java会从两个接口合并,所以现在我必须想出解决这个问题的最佳方法。没有什么叫I12
I1
I2
I12
I1
I2
I12
f
I12.f
(显然如果作者写了一些实际调用的代码I12.f
,他会在出售之前注意到这个问题)。
请注意,我实际上是在寻找这个问题的答案,而不是如何重组我无法更改的代码。我正在寻找可能的最佳启发式方法或确切的解决方案(如果存在)。有关有效示例,请参阅 Gray 的答案(我确信有更强大的解决方案)。
这是一个具体示例,说明两个接口中的单应方法问题如何发生。这是另一个具体的例子:
我有以下 6 个简单的类/接口。它类似于围绕剧院和在其中表演的艺术家的业务。为简单起见,让我们假设它们都是由不同的人创建的。
Set
表示一个集合,如在集合论中:
HRDepartment
用来Set
代表员工。它使用复杂的流程来解码雇用/解雇哪些员工:
员工的Set
范围可能是向雇主提出申请的员工。因此,当complement
在该集合上调用时,所有现有员工都被解雇,而之前申请的所有其他员工都被雇用。
Artist
代表艺术家,例如音乐家或演员。艺术家有自我。当别人称赞他时,这种自我会增加:
Theater
进行Artist
表演,这可能导致Artist
被补充。剧院的观众可以在表演之间评判艺术家。表演者的自尊心越高,观众越可能喜欢Artist
,但如果自尊心超过某个点,观众就会对艺术家产生负面评价:
ArtistSet
只是一个Artist
和一个Set
:
TheaterManager
主持节目。如果剧院的观众对艺术家有负面评价,剧院会与人力资源部门对话,人力资源部门将依次解雇艺术家、聘请新人等:
一旦你尝试实现一个ArtistSet
: 两个超级接口都指定complement
应该做其他事情,这个问题就变得很清楚了,所以你必须以complement
某种方式在同一个类中实现两个具有相同签名的方法。Artist.complement
是 的同形异义词Set.complement
。
c++ - 避免多重继承中的钻石
我必须实现支持抽象数字的数据结构
集合是数字的集合
sorted 是一个排序集合
list 是数字的列表集合(包括重复项)
set 是没有重复的数字的集合。
Linked 和 Array 是保存数据的格式(linked 表示在堆中扩散,而数组表示连续的内存量)
然后是类的组合(图片中称为arraylist的数组列表等)
一个简单的 uml:
最后四个组合中的每一个(图片中的最后一行)都需要实现一个方法调用 sorted 来制作它们自己的排序副本(返回 Sorted 类型)。我想创建 4 个新类,它们是从 sorted 和最后一行中的类继承的(例如,从 Sorted 类和 ArrayList 类继承的 ArrayListSorted 类),但后来我遇到了菱形问题(在同一个例子中,Sorted 和ArrayList 都是 Collection 的后代)
设计上有什么更好的主意吗?
c++ - 这个钻石继承UB是MinGW中的一个错误吗?
我有这样的代码。它可以在 Windows 8 下的 MSVC 2012 x64、g++ 4.7 和 Clang++ 3.2(x86 和 x64)下在 Ubuntu 12.10 和 13.04 下按预期工作。但是,带问号的行在使用 MinGW 4.7 x86 编译时显示未定义的行为或 MinGW 4.8 x64(对不起,我以为我做到了)。
调试器输出表明此时链接到 TargetClass 的 vtable 存在问题。放置断点表明 TargetClass::operator string() 加载了严重取消引用的对象。然而,明确的 dynamic_cast 会产生正确的输出。
我想知道什么可能导致这个问题。如果是MinGW的bug,估计一出现就解决了,因为它打破了C++的核心概念之一。
multiple-inheritance - Coq 中的致命钻石
我正在尝试创建一个相当直接的类型层次结构。这是一个最小的工作示例:
最后一次强制生成以下警告:
实际上,从R12
to R0
(or Sortclass
) 的强制转换可以采用两种不同的路径。而且我理解为什么 Coq 在一般情况下会不允许这样做。因为……它们中的哪一个会被使用?
但是,在这种情况下,可以证明两条路径的强制转换R1_0 (R12_1 r12)
是R2_0 (R12_2 r12)
完全相同的。但我仍然无法添加以下看似有效的公理:
问题:那么有没有办法让 Coq 相信这是可以的?
c++ - C++ 死亡钻石
好的,所以当您完全控制所有类时,我了解如何解决死亡继承钻石的问题,但是如果您只能控制要从两者继承的最后一个类怎么办所以我有这个:
我没有办法只编辑 B 和 C D,有没有简单的方法可以做到这一点?
c++ - c++ 虚拟/非虚拟 Diamond 继承
给定以下 C++ 代码:
有人可以解释为什么吗C* c = new C()
?会按顺序打印 1 23 然后 16 吗?它如何决定打印的顺序?我知道非虚拟B1
将被最后调用,但为什么A()
首先被调用?感谢您提前提供的帮助和解释。