标签: diamond-problem

带接口的多重继承歧义

我们都知道有关多重遗传的钻石问题 -

   A
  / \
 B   C
  \ / 
   D
Run Code Online (Sandbox Code Playgroud)

这个问题描述了课堂的模糊情况D.如果类A有一个方法,并且/ B和/或C覆盖方法,那么哪个版本的方法会D覆盖?

这个问题是否也适用于Java中的接口?如果没有,Java接口如何克服这个问题?

java oop inheritance interface diamond-problem

23
推荐指数
2
解决办法
9825
查看次数

具有相同名称的C++虚拟覆盖函数

我有类似的东西(简化)

class A
{
  public:
    virtual void Function () = 0;
};

class B
{
  public:
    virtual void Function () = 0;
};

class Impl : public A , public B
{
  public:
        ????
};
Run Code Online (Sandbox Code Playgroud)

如何为A实现Function()和为B实现Function()?Visual C++允许您只定义内联的特定函数(即不在cpp文件中),但我认为它是一个扩展.海湾合作委员会抱怨这一点.是否有标准的C++方式告诉编译器我要覆盖哪个函数?

(visual c ++ 2008)

class Impl : public A , public B
{
  public:
     void A::Function () {  cout << "A::Function" << endl; }
     void B::Function () {  cout << "B::Function" << endl; }
};
Run Code Online (Sandbox Code Playgroud)

谢谢!

c++ virtual overriding diamond-problem

20
推荐指数
2
解决办法
4160
查看次数

钻石继承(C++)

我知道钻石继承被认为是不好的做法.但是,我有2个案例,我认为钻石继承可以很好地适应.我想问一下,您是否会建议我在这些情况下使用钻石继承,或者是否有其他设计可能更好.

案例1:我想在我的系统中创建代表不同类型"动作"的类.这些操作按以下几个参数进行分类:

  • 动作可以是"读取"或"写入".
  • 动作可以延迟或没有延迟(它不仅仅是1个参数.它会显着改变行为).
  • 动作的"流类型"可以是FlowA或FlowB.

我打算有以下设计:

// abstract classes
class Action  
{
    // methods relevant for all actions
};
class ActionRead      : public virtual Action  
{
    // methods related to reading
};
class ActionWrite     : public virtual Action  
{
    // methods related to writing
};
class ActionWithDelay : public virtual Action  
{
    // methods related to delay definition and handling
};
class ActionNoDelay   : public virtual Action  {/*...*/};
class ActionFlowA     : public virtual Action  {/*...*/};
class ActionFlowB     : public …
Run Code Online (Sandbox Code Playgroud)

c++ oop inheritance multiple-inheritance diamond-problem

19
推荐指数
3
解决办法
1万
查看次数

通过支配地位继承 - 这真的很糟糕吗?

我是其中一个必须使用0警告编译代码的人之一.通常我尊重编译器,如果它发出警告,我会把它作为一个标志,我应该稍微修改我的代码.如果我必须告诉编译器忽略给定的警告,我会抽搐一下.

但是这个我似乎无法绕过,从我可以告诉我没有做任何"坏事".有人认为这是一个糟糕的设计吗?我看不出任何特别讨厌的东西(除了"邪恶的钻石"),但它是完全有效和有用的代码.但它会产生(在MSVC中)2级警告!

class IFoo
{
public:
    virtual void foo() = 0;
};

class Bar : public virtual IFoo
{
public:
    virtual void foo() { std::cout << "Hello, world!"; }
};

class Baz : public virtual IFoo
{

};

class Quux : public Bar, public Baz
{

};
Run Code Online (Sandbox Code Playgroud)

现在,如果我创建一个Quux对象,应该期望调用Bar :: foo实现.MSVC非常有帮助:它警告我不够模棱两可?

警告C4250:'Quux':通过优势继承'Bar :: Bar :: foo'

现在我知道我可以用一个pragma来关闭这个警告,但这不是我在这里问的问题.我是否应该在这里听编译器,或者这只是一个非常过分热心的警告?

c++ visual-c++ diamond-problem

19
推荐指数
1
解决办法
4563
查看次数

多重继承+虚函数混乱

我有一个像这样的钻石多重继承场景:

    A
  /   \
 B     C
  \   /
    D
Run Code Online (Sandbox Code Playgroud)

公共父A定义了虚函数fn().
B和C都可以定义fn()吗?
如果是,那么下一个问题是 - D可以访问B和C的fn()而不消除歧义吗?我假设有一些语法...
而D是否有可能在不知道谁是B和C的情况下做到这一点?B和C可以替换为其他类,我希望D中的代码是通用的.

我想要做的是让D以某种方式枚举它在其祖先中具有的fn()的所有实例.这是否可能在某些其他方面表示虚函数?

c++ virtual-functions multiple-inheritance diamond-problem

17
推荐指数
3
解决办法
3万
查看次数

多重继承和纯虚函数

以下代码:

struct interface_base
{
    virtual void foo() = 0;
};

struct interface : public interface_base
{
    virtual void bar() = 0;
};

struct implementation_base : public interface_base
{
    void foo();
};

struct implementation : public implementation_base, public interface
{   
    void bar();
};

int main()
{
    implementation x;
}
Run Code Online (Sandbox Code Playgroud)

无法编译时出现以下错误:

test.cpp: In function 'int main()':
test.cpp:23:20: error: cannot declare variable 'x' to be of abstract type 'implementation'
test.cpp:16:8: note:   because the following virtual functions are pure within 'implementation':
test.cpp:3:18: note:    virtual …
Run Code Online (Sandbox Code Playgroud)

c++ virtual multiple-inheritance diamond-problem

16
推荐指数
2
解决办法
9620
查看次数

Do Derived1::Base and Derived2::Base refer to the same type?

MSVC, Clang and GCC disagree on this code:

struct Base { int x; };
struct Der1 : public  Base {};
struct Der2 : public  Base {};

struct AllDer : public Der1, public Der2 {
    void foo() {
        Der1::Base::x = 5;
    }
};
Run Code Online (Sandbox Code Playgroud)

Godbolt

GCC:

<source>: In member function 'void AllDer::foo()':    
<source>:10:21: error: 'Base' is an ambiguous base of 'AllDer'    
   10 |         Der1::Base::x = 5;    
      |                     ^    
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

Clang gives a similar error, and MSVC gives no error.

Who …

c++ multiple-inheritance qualified-name diamond-problem language-lawyer

15
推荐指数
2
解决办法
253
查看次数

C++多重继承防止钻石

有没有办法在C++中定义类Foo,以便

  1. 我可以继承它
  2. 我不能从它"钻石继承"

class Cat: public Foo{} // okay
class Dog: public Foo{} // okay
class Weird: public Cat, public Dog {} // I want this to throw a compiler error
Run Code Online (Sandbox Code Playgroud)

c++ inheritance virtual-inheritance diamond-problem

14
推荐指数
1
解决办法
2103
查看次数

C++ - 在不使用RTTI/dynamic_cast的情况下向下转换钻石形状的继承对象

我目前正致力于在非RTTI平台(Android)上集成使用大量RTTI内容的第三方软件包.基本上,我做了自己的RTTI实现,但我遇到了问题.

问题是很多类都有钻石继承问题,因为所有类派生自相同的基类(对象)..所以,如果我想从基类转发到派生类,我必须使用一个dynamic_cast - 但RTTI不可用!当没有dynamic_cast的虚拟继承时,如何将对象从父对象转换为子对象?

它看起来像这样:

class A 
{
public:
 virtual char* func() { return "A"; };
};
class B : public virtual A
{
public:
 //virtual char* func() { return "B"; };
};
class C : public virtual A 
{
public:
 //virtual char* func() { return "C"; };
};

class D : public B, public C 
{
public:
 //virtual char* func() { return "D"; };
};

D d;
A* pa = static_cast<A*>(&d);
D* pd = static_cast<D*>(pa); // can't do that! …
Run Code Online (Sandbox Code Playgroud)

c++ casting multiple-inheritance rtti diamond-problem

14
推荐指数
2
解决办法
9261
查看次数

什么是多重继承?

我将以下内容称为"多重继承":

  • 通过继承一个或多个后代,直接继承一次类,间接继承一次或多次
  • 通过继承两个或多个后代来间接继承一个类两次或更多次

我想知道它是否存在以及如何明确地访问嵌入的子对象.

1.)[ 专业C++,2 编] 中指明了编译程序不能有直接继承其两个直接父类和所述父的父类.这是真的吗?

鉴于a GrandParentParent,扩展GrandParent,VC12和g ++允许a GrandChild直接从两者ParentGrandParent.继承.在VC12和g ++中,可以按如下方式定义这些类:

GrandParent声明一个int num数据成员.除继承之外,Parent声明自己的.除了继承's和s 之外,它还声明了它自己.numGrandParentnumGrandChildnumParentGrandParentnum

VC12似乎允许明确的成员访问,但g ++只允许它在某些情况下.

#include <iostream>
using std::cout;
using std::endl;

struct GrandParent { int num; };
struct Parent : GrandParent { int num; };
struct GrandChild : GrandParent, Parent { int num; };

int main()
{
    GrandChild gc;
    gc.num = …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance multiple-inheritance diamond-problem

14
推荐指数
1
解决办法
964
查看次数