C++ 从抽象基类的多个部分实现继承?
一个抽象接口是否可以有多个部分实现,然后使用多个继承将这些部分实现收集到一个具体类中 我有以下示例代码:C++ 从抽象基类的多个部分实现继承?,c++,multiple-inheritance,virtual-inheritance,C++,Multiple Inheritance,Virtual Inheritance,一个抽象接口是否可以有多个部分实现,然后使用多个继承将这些部分实现收集到一个具体类中 我有以下示例代码: #include <iostream> struct Base { virtual void F1() = 0; virtual void F2() = 0; }; struct D1 : Base { void F1() override { std::cout << __func__ << std::endl; } };
#include <iostream>
struct Base
{
virtual void F1() = 0;
virtual void F2() = 0;
};
struct D1 : Base
{
void F1() override { std::cout << __func__ << std::endl; }
};
struct D2 : Base
{
void F2() override { std::cout << __func__ << std::endl; }
};
// collection of the two partial implementations to form the concrete implementation
struct Deriv : D1, D2
{
using D1::F1; // I added these using clauses when it first didn't compile - they don't help
using D2::F2;
};
int main()
{
Deriv d;
return 0;
}
从Base
尝试:
struct D1 : virtual Base
{
void F1() override { std::cout << __func__ << std::endl; }
};
struct D2 : virtual Base
{
void F2() override { std::cout << __func__ << std::endl; }
};
结构D1:虚拟基
{
void F1()重写{std::cout
一个抽象接口可以有许多部分实现,然后使用多个继承将这些部分实现收集到一个具体类中吗
对
每个Base
基类子对象都会带来两个纯虚函数。您希望在Deriv
中包含多少基类子对象
- 如果您想要2
Base子对象、Base
和Deriv::D1::Base
(因此从Deriv::D2::Base
到Deriv&
的转换将是不明确的),那么您将在Base&
:Deriv
,Deriv::D1::Base::F1()
,Deriv::D1::Base::F2()中有4个不同的虚拟函数
,Deriv::D2::Base::F1()
。只实现了第一个和最后一个,所以中间的两个是纯虚拟的:Deriv::D2::Base::F2()
,Deriv::D1::Base::F2()
。您有两个完全独立的继承关系:Deriv::D2::Base::F1()
继承自Deriv
和D1
继承自Deriv
D2
Base
Base类子对象Deriv::Base
,则在Deriv
中只有两个不同的虚拟函数:Base::F1()
,Base::F2()
C
来说,只有一个M
类成员子对象。这些关系是一对一的
另外,虚拟继承是一种更“抽象的”:struct D:virtual B
意味着每个D
对象都与B
基类子对象相关联,但这种关系是多对一的,就像struct C{M&M;}
通常,对于任何派生类D
(此处Deriv
),以及D
(此处base
)的任何虚拟基B
,D
的所有基类都是虚拟派生自B
(此处Deriv::D1
,Deriv::D2
)有助于重写基类中的虚拟函数:
被Base::F1()
Deriv::D1::F1()覆盖
被Base::F2()
Deriv::D2::F2()覆盖
Deriv
成为一个具体的类,您必须显式地实现F1()
和F2()
虚拟函数签名(在Deriv
中有4个虚拟函数,但只有2个不同的签名),因此您需要2个函数定义:
struct Deriv : D1, D2
{
void F1() override { D1::F1(); }
void F2() override { D2::F2(); }
};
请注意,
Deriv::F1()
覆盖了Deriv::D1::F1()
和Deriv::D2::F1()
+1作为一个简短的、自包含的示例。“抽象接口”一般来说:抽象接口意味着虚拟继承(特殊情况可能有所不同)。struct D1:Base
”这里使用公共继承有什么原因吗?对客户端代码使用D1
感兴趣吗?@curiousguy没有原因-刚刚举了一个例子-在我的特殊用法中,我使用公共和私有的混合,这取决于“不完整的基类”的情况抽象基类?@curiousguy不一定是抽象的,只要至少有一个未实现的方法。@juanchopanza什么是抽象类?@curiousguy啊哈!我明白你的意思。如果实现的方法是“抽象的”,我仍然很难想象一个有一堆方法的类但我应该尊重C++术语。“好家伙,在那种情况下,我把它全部收回。”
struct Deriv : D1, D2
{
using D1::F1; // I added these using clauses when it first didn't compile - they don't help
using D2::F2;
};
struct Deriv : D1, D2
{
void F1() override { D1::F1(); }
void F2() override { D2::F2(); }
};