具有抽象基类的 C++ 虚拟继承

标签 c++ inheritance virtual abstract radix

我会尽力阐明我的意图,因为可能有不止一种方法可以实现这一点。首先,我有一个带有虚函数 SayHi() 的抽象基类 FooBaseFoo1 是众多派生类之一。

class FooBase {
public:
    virtual void SayHi() = 0;
};

class Foo1 : public FooBase {
public:
    virtual void SayHi() {
        std::cout<<"Foo1 says Hi\n";
    }
};

我还有一个 Component 类,有时我想将 Foo.. 类实现为 Components。我使用了一个模板类,以便 FooBase 的任何子类都可以有一个 Component 包装器。

class FooComponentBase : public Component {
public:
    virtual FooBase& GetFoo() = 0;
};

template <class T>
class FooComponent : public FooComponentBase {
private:
    T m_foo;
public:
    virtual FooBase& GetFoo() {return m_foo;}
};

现在 FooComponentBase 是包含 FooBase 任何子类的组件的接口(interface):

void DoTest() {
    FooComponentBase* pFooComponent = new FooComponent<Foo1>;
    pFooComponent->GetFoo().SayHi();                            // "Foo1 says Hi"
    delete pFooComponent;
}

到目前为止一切顺利,这有效。但如果 FooComponent 继承自 FooBase 可能会更简洁,因此我们不需要通过 GetFoo() 来访问 FooBase 的方法。

// Inherited version

class FooComponentBase : public Component {};

template <class T>
class FooComponent : public FooComponentBase, public T {};

不幸的是,FooComponentBase 无法访问 FooBase,尽管它的所有派生类都可以;

void DoTest() {
    FooComponentBase* pFooComponent = new FooComponent<Foo1>;
    pFooComponent->SayHi();     // Error, FooComponentBase has no SayHi() function
    delete pFooComponent;
}

我找不到方法来完成这项工作。看来应该有一种方法,也许使用虚拟继承;

class FooComponentBase : public Component, virtual public FooBase {};

但这也无法编译,因为我们无法实例化抽象类。我希望我的意图很明确,我想让 FooComponentBase 成为一个抽象基类,就像 FooBase 但具有 Component 继承,这样我就可以使用它可以访问 FooComponent 的每种风格。 有没有一种巧妙的方法来做到这一点?

最佳答案

如果您在一处使用虚拟继承,并且希望使用相同的基本实现,则必须在所有地方使用它:

class Foo1 : public virtual FooBase {

另一种方法,虽然不太好,但可能适合您,是在 FooComponent 中实现 FooBase 的所有函数:

class FooComponentBase : public Component, public FooBase {
};

template <class T>
class FooComponent : public FooComponentBase {
private:
    T m_foo;
public:
    void SayHi() {m_foo.SayHi();}
};

或者甚至:

class FooComponentBase : public Component, public FooBase {
};

template <class T>
class FooComponent : public FooComponentBase, public T {
public:
    void SayHi() {T::SayHi();}
};

关于具有抽象基类的 C++ 虚拟继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24408567/

相关文章:

c++ - 带有类指针的 if 语句导致段错误

c# - 为 .NET 使用定义此 native 接口(interface)的最佳方法是什么?

java - 在Java中,new TestA()和TestA obj = new TestA()有什么区别?

c++非虚函数就像虚函数一样

c# - 多态和类型转换

c++ - openCV没有匹配函数fillPoly

c++ - 我正在寻找可以在图形编辑程序中进行的任何优化

java - 如何扩展 JPA 实体以仅添加组合

PHP:覆盖静态方法无法按预期工作

apache - 在单个服务器 (IP) 上为多个域(虚拟主机)设置 SSL