【问题标题】:c++ derived class from two same base classc ++派生类来自两个相同的基类
【发布时间】:2014-02-25 20:35:49
【问题描述】:

这是我的课程:

class Base1
{
public:
    Base1();
    ~Base1();

    virtual void main_func()=0;
}

class D1 : public Base1
{
public:
    D1();
    ~D1();

    virtual void main_func(do_d1_main(););
}
class D2 : public Base1
{
public:
    D2();
    ~D2();

    virtual void main_func(){do_d2_main();};
}

class Base2
{
public:
    Base2();
    ~Base2();

    int   m_needed_by_b1;
}
class D12B2: public Base2, public D1, public D2
{
public:
    D12B2();
    ~D12B2();
}

问题来了:

do_main_func1() 和 do_main_func2() 都需要访问 Base2 中的成员 m_needed_by_b1。怎么样?

我可以为class D12B2 中的每个定义虚函数main_func 吗?这将使他们能够访问所有D12B2,包括Base2。我将如何分别指定每个?

我考虑在Base1 中添加一个(受保护的)成员,即指向Base2 对象的指针。这必须由D12B2 设置。似乎有一种更优雅的方法可以做到这一点。

TIA

肯

【问题讨论】:

  • 一种方法(有些人不喜欢)是使用多重继承;使 D1 和 D2 都派生自 both Base1 和 Base2。
  • 在do_d1_main、do_d2_main、do_main_func1 和do_main_func2 之间,您在代码或描述中指定了四件事,其中没有任何定义。 do_d1_main 和 do_main_func1(以及它们对应的 d2)应该是相同的功能吗?
  • 这通常被认为是design/code smell
  • 这是XY Problem
  • @WhozCraig: main_func 被一个只知道这是 Base1 类的对象调用。我使用do_main_funcX() 表示每个 DX::main_func 做不同的事情。 @Brian Bi:这会给我两个单独的 Base2 对象,我试图避免。

标签: c++ inheritance duplicates virtual


【解决方案1】:

似乎有一种更优雅的方法可以做到这一点。

很可能存在 - 不要使用多重继承。

但是,如果你要坚持使用多重继承,有一些事情你必须注意:D1 和D2 应该在D12B2 中虚拟继承以避免菱形问题。假设do_d1_main和do_d2_main实际上是main_func,那么你可以实现一个D12B2::main_func,它可以访问m_needed_by_b1。

但回到原来的注释:

听起来Base1和Base2不应该存在,D1和D2应该是纯抽象类。这会让你留下

class D1
{
public:
    virtual void d1_func() = 0;
};

class D2
{
public:
    virtual void d2_func() = 0;
};

class D12B2 : public virtual D1, public virtual D2
{
public:
    D12B2();
    ~D12B2();

    virtual void d1_func()
    {
        // do something
    }

    virtual void d2_func()
    {
        // do something else
    }

private:
    int m_myData;
};

【讨论】:

  • "...避免钻石问题。"您的意思是“执行菱形图案”吗?没有虚拟继承就没有菱形,这很可能是个问题。
  • @WhozCraig 我的意思是它会避免模棱两可的函数声明问题——我指的是diamond problem。
  • 是的,D1 和 D2 应该虚拟继承,以避免钻石。对不起,我把它漏掉了。但是,两个基类都是需要的(至少我是这么认为的)。示例:base1 是一个线程类,它在单独的线程中创建和运行thread_main()。我定义了两个不同的线程类:音频和视频(它们是 D1 和 D2)。 Base2 是一个通用设备类,具有音频和视频线程所需的功能。 D12B2 是一种特定的设备,它同时具有音频线程和视频线程。
  • @user3182551 这样,这个问题就变成了XY problem。当您不需要(并且可能不应该)时,您正试图将线程视为多态实体。
  • 好吧,我想我正在尝试 XY 的东西。那么为什么我不需要多态实体(或者它是什么?)。如果您的意思是 main_func 不需要是虚拟的,它确实如此,因为运行线程的机制调用了该函数,但它只知道 Base1 类,而不知道任何派生类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-16
  • 2012-11-04
  • 1970-01-01
  • 2017-07-25
相关资源
最近更新 更多