多重虚拟继承
Multiple virtual inheritance
我知道有很多关于 MI 的问题,但是,none 似乎回答了我的问题。我有以下最小示例:
#include <iostream>
struct Base{
virtual void foo() = 0;
};
struct A : public virtual Base{
void foo(){
std::cout << "A::foo()" << std::endl;
}
void foo( int a){
std::cout << "A::foo(int a)" << std::endl;
}
};
struct B : public virtual Base{
virtual void foo( int a ) = 0;
};
struct C : public B,public A{
using A::foo;
};
int main( int argc, char* argv[]){
C c;
c.foo();
c.foo( 1 );
}
其中 Base 和 B 完全是虚拟的 classes 和 A 提供所有实现。但是,代码没有编译,而是给我以下错误消息
mh.cpp: In function ‘int main(int, char**)’:
mh.cpp:22:11: error: cannot declare variable ‘c’ to be of abstract type ‘C’
C c;
^
mh.cpp:17:12: note: because the following virtual functions are pure within ‘C’:
struct C : public B,public A{
^
mh.cpp:15:22: note: virtual void B::foo(int)
virtual void foo( int a ) = 0;
我想要的行为可以通过将 class C
扩展到
来实现
struct C : public B,public A{
using A::foo;
void foo( int a ){
A::foo( a );
}
};
但是,我不想添加这种多余的方法。有什么方法可以实现这个结果吗?
A::foo(int)
无法覆盖 B::foo(int)
除非 A
派生自 B
.
因此,如果您不想在 C
中创建转发覆盖,您的替代方案是:
- 将
foo(int)
纯虚拟重载移动到 Base
- 使
A
派生自 B
- 重构你的接口,这样你就不需要菱形虚拟继承了
不行,如果你继承自一个纯虚class并且你想使用这个派生的class(声明那个类型的对象,不是指针),你必须实现它所有的纯虚方法。
以同样的方式,你可以问以下问题:
class A
{
public:
virtual void foo()=0;
virtual void hello()=0;
}
class B: public A
{
public:
void myFoo();
void hello() { std::cout << "Hello!"; }
}
在class B
中不想用A::foo()
只想用B::myFoo()
怎么办?
在这种情况下,您要么需要为纯虚函数提供一些虚拟实现,要么再次检查您的设计...您可能不应该从 A 继承。
你的情况与此类似。可能你的 class C
不应该继承自 class B
.
- 只需按如下所示替换您的单行。
- 仅从 A.
派生 C
您的代码
struct C : public B,public A{
using A::foo;
};
用下面的代码替换上面的代码,
struct C : public A{
using A::foo;
};
我知道有很多关于 MI 的问题,但是,none 似乎回答了我的问题。我有以下最小示例:
#include <iostream>
struct Base{
virtual void foo() = 0;
};
struct A : public virtual Base{
void foo(){
std::cout << "A::foo()" << std::endl;
}
void foo( int a){
std::cout << "A::foo(int a)" << std::endl;
}
};
struct B : public virtual Base{
virtual void foo( int a ) = 0;
};
struct C : public B,public A{
using A::foo;
};
int main( int argc, char* argv[]){
C c;
c.foo();
c.foo( 1 );
}
其中 Base 和 B 完全是虚拟的 classes 和 A 提供所有实现。但是,代码没有编译,而是给我以下错误消息
mh.cpp: In function ‘int main(int, char**)’:
mh.cpp:22:11: error: cannot declare variable ‘c’ to be of abstract type ‘C’
C c;
^
mh.cpp:17:12: note: because the following virtual functions are pure within ‘C’:
struct C : public B,public A{
^
mh.cpp:15:22: note: virtual void B::foo(int)
virtual void foo( int a ) = 0;
我想要的行为可以通过将 class C
扩展到
struct C : public B,public A{
using A::foo;
void foo( int a ){
A::foo( a );
}
};
但是,我不想添加这种多余的方法。有什么方法可以实现这个结果吗?
A::foo(int)
无法覆盖 B::foo(int)
除非 A
派生自 B
.
因此,如果您不想在 C
中创建转发覆盖,您的替代方案是:
- 将
foo(int)
纯虚拟重载移动到Base
- 使
A
派生自B
- 重构你的接口,这样你就不需要菱形虚拟继承了
不行,如果你继承自一个纯虚class并且你想使用这个派生的class(声明那个类型的对象,不是指针),你必须实现它所有的纯虚方法。 以同样的方式,你可以问以下问题:
class A
{
public:
virtual void foo()=0;
virtual void hello()=0;
}
class B: public A
{
public:
void myFoo();
void hello() { std::cout << "Hello!"; }
}
在class B
中不想用A::foo()
只想用B::myFoo()
怎么办?
在这种情况下,您要么需要为纯虚函数提供一些虚拟实现,要么再次检查您的设计...您可能不应该从 A 继承。
你的情况与此类似。可能你的 class C
不应该继承自 class B
.
- 只需按如下所示替换您的单行。
- 仅从 A. 派生 C
您的代码
struct C : public B,public A{ using A::foo; };
用下面的代码替换上面的代码,
struct C : public A{ using A::foo; };