我想知道什么是“虚拟基类”以及它的含义。
让我举个例子:
class Foo
{
public:
void DoSomething() { /* ... */ }
};
class Bar : public virtual Foo
{
public:
void DoSpecific() { /* ... */ }
};
我想知道什么是“虚拟基类”以及它的含义。
让我举个例子:
class Foo
{
public:
void DoSomething() { /* ... */ }
};
class Bar : public virtual Foo
{
public:
void DoSpecific() { /* ... */ }
};
当前回答
虚拟类与虚拟继承不同。虚拟类你不能实例化,虚拟继承完全是另一回事。
维基百科描述得比我好。http://en.wikipedia.org/wiki/Virtual_inheritance
其他回答
除了前面提到的多重继承和虚拟继承之外,在Dr Dobb's Journal上还有一篇非常有趣的文章:多重继承被认为是有用的
钻石继承可运行的用法示例
这个示例展示了如何在典型场景中使用虚拟基类:解决菱形继承问题。
考虑下面的工作示例:
main.cpp
#include <cassert>
class A {
public:
A(){}
A(int i) : i(i) {}
int i;
virtual int f() = 0;
virtual int g() = 0;
virtual int h() = 0;
};
class B : public virtual A {
public:
B(int j) : j(j) {}
int j;
virtual int f() { return this->i + this->j; }
};
class C : public virtual A {
public:
C(int k) : k(k) {}
int k;
virtual int g() { return this->i + this->k; }
};
class D : public B, public C {
public:
D(int i, int j, int k) : A(i), B(j), C(k) {}
virtual int h() { return this->i + this->j + this->k; }
};
int main() {
D d = D(1, 2, 4);
assert(d.f() == 3);
assert(d.g() == 5);
assert(d.h() == 7);
}
编译并运行:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
如果我们移除virtual into:
class B : public virtual A
我们会得到一堵关于GCC无法解析D成员和通过a继承两次的方法的错误墙:
main.cpp:27:7: warning: virtual base ‘A’ inaccessible in ‘D’ due to ambiguity [-Wextra]
27 | class D : public B, public C {
| ^
main.cpp: In member function ‘virtual int D::h()’:
main.cpp:30:40: error: request for member ‘i’ is ambiguous
30 | virtual int h() { return this->i + this->j + this->k; }
| ^
main.cpp:7:13: note: candidates are: ‘int A::i’
7 | int i;
| ^
main.cpp:7:13: note: ‘int A::i’
main.cpp: In function ‘int main()’:
main.cpp:34:20: error: invalid cast to abstract class type ‘D’
34 | D d = D(1, 2, 4);
| ^
main.cpp:27:7: note: because the following virtual functions are pure within ‘D’:
27 | class D : public B, public C {
| ^
main.cpp:8:21: note: ‘virtual int A::f()’
8 | virtual int f() = 0;
| ^
main.cpp:9:21: note: ‘virtual int A::g()’
9 | virtual int g() = 0;
| ^
main.cpp:34:7: error: cannot declare variable ‘d’ to be of abstract type ‘D’
34 | D d = D(1, 2, 4);
| ^
In file included from /usr/include/c++/9/cassert:44,
from main.cpp:1:
main.cpp:35:14: error: request for member ‘f’ is ambiguous
35 | assert(d.f() == 3);
| ^
main.cpp:8:21: note: candidates are: ‘virtual int A::f()’
8 | virtual int f() = 0;
| ^
main.cpp:17:21: note: ‘virtual int B::f()’
17 | virtual int f() { return this->i + this->j; }
| ^
In file included from /usr/include/c++/9/cassert:44,
from main.cpp:1:
main.cpp:36:14: error: request for member ‘g’ is ambiguous
36 | assert(d.g() == 5);
| ^
main.cpp:9:21: note: candidates are: ‘virtual int A::g()’
9 | virtual int g() = 0;
| ^
main.cpp:24:21: note: ‘virtual int C::g()’
24 | virtual int g() { return this->i + this->k; }
| ^
main.cpp:9:21: note: ‘virtual int A::g()’
9 | virtual int g() = 0;
| ^
./main.out
在GCC 9.3.0, Ubuntu 20.04上测试。
解释使用虚拟基的多重继承需要c++对象模型的知识。最好是在一篇文章中,而不是在评论框中,清楚地解释这个主题。
我发现最好的、易读的解释是这篇文章,它解决了我对这个问题的所有疑问:http://www.phpcompiler.org/articles/virtualinheritance.html
在读完这篇文章之后,你真的不需要再阅读关于这个主题的任何其他内容了(除非你是编译器作者)…
虚拟类与虚拟继承不同。虚拟类你不能实例化,虚拟继承完全是另一回事。
维基百科描述得比我好。http://en.wikipedia.org/wiki/Virtual_inheritance
你有点让人困惑了。我不知道你是否混淆了一些概念。
op中没有虚基类,只有基类。
你做了虚拟继承。这通常用于多重继承,以便多个派生类使用基类的成员而不复制它们。
不实例化具有纯虚函数的基类。这需要Paul掌握的语法。通常使用它是为了派生类必须定义这些函数。
我不想再解释了,因为我不太明白你在问什么。