代码之家  ›  专栏  ›  技术社区  ›  HiroIshida

C++多重继承:实现具有重叠虚函数的接口[重复]

  •  1
  • HiroIshida  · 技术社区  · 1 年前

    我试图在C++中设计一个类层次结构,其中我有一个基本接口 FooInterface 具有纯虚函数 foo() ,以及另一个接口 FooBarInterface 这应该延伸 Foo接口 并添加附加功能 bar() 然后我有一节课 Foo 实现 foo() Foo接口 ,和一个类 FooBar 继承自 Foo FooBar接口 并实施 bar() . 我的目标是拥有 func 函数接受a std::shared_ptr 对于同时实现这两个功能的任何对象 foo() bar() .

    #include <memory>
    
    class FooInterface {
    public:
        virtual void foo() = 0;
    };
    
    class FooBarInterface : public FooInterface {
    public:
        virtual void bar() = 0;
    };
    
    class Foo : public FooInterface {
    public:
        void foo() override {};
    };
    
    class FooBar : public Foo, public FooBarInterface {
    public:
        void bar() override {};
    };
    
    void func(std::shared_ptr<FooBarInterface> fb) {}
    
    int main() {
        func(std::make_shared<FooBar>());
    }
    

    注意:省略虚拟析构函数。

    然而,这段代码无法编译,可能是因为 foo() 在里面 FooBar接口 在中未被覆盖 FooBar 尽管如此 FooBar 继承自 Foo ,实现 foo() .

    我应该如何修改我的代码?或者你有什么设计模式值得我参考吗?

    1 回复  |  直到 1 年前
        1
  •  1
  •   m3lvinger    1 年前

    如果你想让FooBar::foo使用foo的实现,你可以调用它。

    class FooBar : public Foo, public FooBarInterface {
    public:
        void foo() override { Foo::foo(); } 
        void bar() override {};
    };
    
        2
  •  1
  •   Pete Becker    1 年前

    我迷路了 Foo s和the Bar s和the Interfaces ,所以我要重写类层次结构,保持相同的结构:

    struct Base {
        virtual void foo() = 0;
    }
    
    struct Intermediate1 : Base {
    };
    
    struct Intermediate2 : Base {
        void foo();
    }
    
    struct Derived : Intermediate1, Intermediate2 {
    };
    
    Derived d; // error: can't create object of an abstract type
    

    一个对象 Derived 有两个类型为的子对象 Base ,一个通过 Intermediate1 另一个过来了 Intermediate2 因此,它具有两种不同的功能 foo ,一个通过 中间体1 还有一个进来了 中间体2 .由于 中间体1 不覆盖 Base::foo (以及 衍生 也不会覆盖它),它仍然是一个纯虚函数,所以 衍生 是一个抽象类,不能实例化。

    另一方面(以及有多少人认为“接口”是继承的(引用是因为C++没有“接口”的正式概念),类似的层次结构可能如下:

    struct Base {
        virtual void foo() = 0;
    }
    
    struct Intermediate1 : virtual Base {
    };
    
    struct Intermediate2 : virtual Base {
        void foo();
    }
    
    struct Derived : Intermediate1, Intermediate2 {
    };
    
    Derived d; // okay, via "dominance"
    

    注意添加 virtual 对于直接从中导出的类 基地 .现在是一个类型为的对象 衍生 只有一个子对象类型 基地 ,以及 统治地位 规则说,在 衍生 , Intermediate2::foo 覆盖 基:foo ,即使中没有覆盖 中间体1 所以 中间体1 它本身是一个抽象类,但是 衍生 不是,即使它没有覆盖 基:foo ; 通过覆盖 中间体2 足够了。