在C++中能否隐藏继承层次结构的部分?

11
请考虑以下内容:
B公开继承自类A。它们都在一个库中提供,我无法修改它们。
我想实现一个从B派生的类Foo,但我只希望允许Foo的用户使用AFoo的公共函数(而不是B的函数)。对于他们来说,FooB继承这一事实并不重要,这基本上是我不能避免的实现细节。
因此,我希望FooA公开继承,但从B私有继承。
在C++中是否有某种结构可以实现这一点?
我必须补充说明,并非所有情况下都可以使用虚拟继承,因为在我的情况下,A派生自QObject(请参见如果QObject被直接派生,使用*virtual*多重继承是否安全?)。

(注:对于有兴趣的人:在我的情况下,AQWindowBQt3DExtras :: Qt3DWindow


1
struct foo : A { B b; } 这段代码能够正常工作吗? - Danh
2
只需不要记录您的类派生自B。说它派生自A即可。这并不是阻止决心想要访问B的用户的方法,但其他方法也没有。 - n. m.
2个回答

9

在C++中,最接近的方法是这样的:

class Foo : private B {
  public:
    using A::foo; // Expose function foo in Foo's API.
    using A::bar;
    operator A&() { return *this; } // Implicit conversion to `A` when needed.
    operator A const&() const { return *this; }
};

2
A * a = pointer_to_foo,这是Qt的重要部分,但它不起作用。 - Danh
@Danh,更喜欢使用引用的另一个原因是指针强制转换不能添加,因为它们是内置类型。原始作者将不得不显式地进行转换。 - StoryTeller - Unslander Monica
是的,我也喜欢使用引用,但据我所知,这就是Qt通常的工作方式。 - Danh
@StoryTeller 考虑提供到 const A & 的转换。 - Ralph Tandetzky
@RalphTandetzky,是的,那是个好主意。我对 C++ 的抱怨是没有一种方法可以一次性提供两者。 - StoryTeller - Unslander Monica
确实,这个解决方案满足了我的需求。在我的情况下,由于继承层次结构(QWindowQObject有许多函数),头文件变得相当大,因此我不得不使QObject成为该类的友元以允许信号槽连接。此外,由于我还从我的类Foo派生,所以我用受保护的继承替换了私有继承。 - oLen

2

既然这是Qt,我认为这是你能做的最接近的:

struct Foo : A {
    // override all function of A, forward its to B
private:
    B b; // or pointer to B, it's depend on your design
};

这将在 Foo 中给你两个 A,一个是继承的,另一个是 b 的一部分。(具体来说,有两个 QWindow,听起来不对——这只是一个窗口,不是吗?)这可能不是想要的。我还假设一个 Foo 必须 一个 B,例如因为指向它的指针被存储为指向 B 的指针。 - Peter - Reinstate Monica
@PeterA.Schneider OP 说过:“对他们来说,Foo从B继承并不相关。” - Danh
不是为了用户,但某个地方必须有一个需求——毕竟这是无法避免的。 - Peter - Reinstate Monica
@PeterA.Schneider 我认为 OP 是有这个想法的_这是一个我无法避免的实现细节_让他稍微澄清一下这个要求。 - Danh
理想情况下,我们希望有一个普通的 QWindow,其中包含一个用于3D表示的小部件,这将对应于此答案。然而,在Qt3D中,目前必须为其创建一个窗口。原则上,可以使用 QWidget::createWindowContainer() 嵌入窗口,但我认为问题本身很有趣,可能会在另一个上下文中出现,这就是我提出它的原因。 - oLen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接