使用姐妹继承

Posted

技术标签:

【中文标题】使用姐妹继承【英文标题】:using sister inheritance 【发布时间】:2012-04-10 05:39:50 【问题描述】:

让我们假设一些(遗留)代码,不能被触及,声明

struct B
 public:
  void f()
;

让我们假设有

struct A
 public:
  virtual void f()=0;
;

是否可以在不显式调用 f() 的情况下进行 A 子类调用 B::f,即代替

  struct C: public A, public B
   void f()
   B::f();
  
 ;

有类似的东西

 struct C:virtual public A,virtual public B

 ;

(注意最后一个类是抽象的,因为编译器 A::f 没有定义)

【问题讨论】:

B::f() 有什么问题?这是调用B::f()的正确方法。 想象你有 100 个函数 ;) 不,基成员函数不可能为另一个基类实现纯虚函数。那是行不通的。你所拥有的一切都很好。 好的,我有一百个函数,这和这个问题有什么关系? 我猜他想避免编写样板代码。 【参考方案1】:

直接在 C++ 中,不可能基于 B 的函数与 A 的某些隐式匹配进行多态分派。您可以使用 gccxml 或其他类似产品进行某种代码生成,但如果只有一百个函数,那么宏无论如何都可以将转发减少到单行 - 不值得引入额外的工具,除非您有成千上万的这些要做。

【讨论】:

"基于 B 的函数与 A 的一些隐式匹配进行多态调度" G++ 使用来支持所谓的“签名”:Type Abstraction using Signatures “在 GNU C++ 中,您可以使用关键字签名将完全抽象的类接口定义为数据类型。您可以使用签名指针将此抽象与实际类连接起来。(...)子类型化变得独立于继承。(...)签名允许您使用现有的类层次结构作为签名类型的实现。” @curiousguy:这是普遍的(在 gcc 3 中历史给定的删除)兴趣,但我看不出它对于做问题所寻求的或更普遍的“基于多态的调度”有什么用处B的函数与A的一些隐式匹配”你引用。鉴于signature S void f(); ; ... S* p = static_cast<A&>(this); p->f(); 在功能上似乎等同于说std::function<void(void)> x = std::bind(&B::f, this); x(); - 两者似乎都比问题中的B::f(); 更笨拙。不确定我是否遗漏了什么......?【参考方案2】:

实现A,将其委托给B

class A_Impl : public A

public:
    virtual void f()
    
        b.f();
    
private:
    B b;

通过从A_Impl派生来实现C

class C: public A_Impl

;

或者,如果您只想在继承层次结构中显示A,则公开派生自A,私下派生自A_Impl

class C: public A, private virtual A_Impl

;

【讨论】:

【参考方案3】:

你可以这样做:

void C::f() 
    B* b = this;
    b->f();

【讨论】:

谢谢,但是我不想写每个函数的实现(另外,这个版本比我写的有什么好处?) @FabioDallaLibera:我不明白。如果您不想在C 中编写一个名为f 的函数,那么为什么要声明这样的函数?在这种情况下,C::f 的实现与您的实现之间没有区别,除了这个不使用您想要避免的 B::f【参考方案4】:

不,你不能那样做。从您向我们展示的 sn-p 看来,B 应该是C 的成员,通过组合而不是继承。您只需要编写一些转发函数(或自动为您生成它们的脚本)。

【讨论】:

【参考方案5】:

所以,您在 A 中有 100 个纯虚函数,在 B 中实现了这些函数,并且您希望避免在 C 中编写重新实现所有这些函数来调用 B。没有办法让编译器使用 B 的实现自动地。 重新考虑继承图,而不是与编译器斗争(每次你都会输!)。也许让 B 成为 A 的子类,然后从 B 派生 C。或者将 100 个方法从 B 中分解出来并放入 A 的具体子类中。

编程是在工具提供的限制内解决问题的艺术。当您发现自己与工具不一致时,您需要重新考虑解决问题的方法或使用不同的工具。

【讨论】:

问题是说B不能被碰,所以不能让它成为A的子类,也不能把方法移出它。

以上是关于使用姐妹继承的主要内容,如果未能解决你的问题,请参考以下文章

使用 'order' 属性在兄弟姐妹之间定位弹性项目

使用 jquery 切换兄弟姐妹

仅使用 CSS 均衡兄弟姐妹的高度? [复制]

使用 CSS 定位接下来的几个兄弟姐妹

如何使用 Xpath java 仅在兄弟姐妹中查找节点?

使用 React Hooks 更改元素类名称和兄弟姐妹