在 C++11 (N3485) 10.1.4 [class.mi] 中它说:
For each distinct occurence of a non-virtual base class in the class lattice of the most derived class, the most derived object shall contain a corresponding distinct base class subobject of that type.
For each distinct base class that is specified virtual, the most derived class shall contain a single base class object of that type.
考虑以下 C++11 代码:
struct B {};
struct BV : virtual B {};
struct BN : B {};
struct C1 : BV, BN {};
struct C2 : BV, BN {};
struct D : C1, C2 {};
首先,为了清楚起见,D的类格有多少个顶点?
其次,标准要求D类型的最派生对象有多少个不同的B类型子对象?
更新:
下面哪个是类格?
(1)
B B B B
^ ^ ^ ^
| | | |
BV BN BV BN
^ ^ ^ ^
| | | |
\ / \ /
C1 C2
\ /
\ /
- D -
(2)
B<---------
^ \
| |
| B | B
| ^ | ^
| | | |
BV BN BV BN
^ ^ ^ ^
| | | |
\ / \ /
C1 C2
\ /
\ /
- D -
(3)
B
/ \
/ \
BV BN
| \ / |
| \/ |
| / \ |
| / \|
C1 C2
\ /
\ /
D
如果意图是 (1) 那么是否不可能有任何不是树的 DAG? (即钻石是不可能的)如果是这样,将它称为类树不是更好吗?
如果是 (2) 是否足以说“对于类格中基类的每次出现,都有一个相应的基类子对象”?也就是说,如果格子的构建已经依赖于虚拟和非虚拟基类关系来选择边和顶点?
如果是 (3) 那么标准中的语言是不是不正确,因为类格中的类只能出现一次?
最佳答案
Which of the following is the class lattice?
2
演示:
#include <iostream>
struct B {};
struct BV : virtual B {};
struct BN : B {};
struct C1 : BV, BN {};
struct C2 : BV, BN {};
struct D : C1, C2 {};
int
main()
{
D d;
C1* c1 = static_cast<C1*>(&d);
BV* bv1 = static_cast<BV*>(c1);
BN* bn1 = static_cast<BN*>(c1);
B* b1 = static_cast<B*>(bv1);
B* b2 = static_cast<B*>(bn1);
C2* c2 = static_cast<C2*>(&d);
BV* bv2 = static_cast<BV*>(c2);
BN* bn2 = static_cast<BN*>(c2);
B* b3 = static_cast<B*>(bv2);
B* b4 = static_cast<B*>(bn2);
std::cout << "d = " << &d << '\n';
std::cout << "c1 = " << c1 << '\n';
std::cout << "c2 = " << c2 << '\n';
std::cout << "bv1 = " << bv1 << '\n';
std::cout << "bv2 = " << bv2 << '\n';
std::cout << "bn1 = " << bn1 << '\n';
std::cout << "bn2 = " << bn2 << '\n';
std::cout << "b1 = " << b1 << '\n';
std::cout << "b2 = " << b2 << '\n';
std::cout << "b3 = " << b3 << '\n';
std::cout << "b4 = " << b4 << '\n';
}
我的输出:
d = 0x7fff5ca18998
c1 = 0x7fff5ca18998
c2 = 0x7fff5ca189a0
bv1 = 0x7fff5ca18998
bv2 = 0x7fff5ca189a0
bn1 = 0x7fff5ca18998
bn2 = 0x7fff5ca189a0
b1 = 0x7fff5ca189a8
b2 = 0x7fff5ca18998
b3 = 0x7fff5ca189a8
b4 = 0x7fff5ca189a0
If it is (2) wouldn't it be sufficient to say "for each occurence of a base class in the class lattice there is a corresponding base class subobject" ?. That is, if the construction of the lattice already depends on virtual and non-virtual base class relationships to select edges and vertices?
合并您的建议...
A base class specifier that contains the keyword virtual, specifies a virtual base class. For each
distinctoccurrence of anon-virtualbase class in the class latticeof the most derived class, the most derived object (1.8) shall containthere is a correspondingdistinctbase class subobjectof that type.For each distinct base class that is specified virtual, the most derived object shall contain a single base class subobject of that type.
我不是标准语言一半的专家。但是,当我阅读您修改后的规范时,我看不出如何:
class V { /∗...∗/ };
class A : virtual public V { /∗ ... ∗/ };
class B : virtual public V { /∗ ... ∗/ };
class C : public A, public B { /∗...∗/ };
图 4 中的结果:
V
/ \
/ \
A B
\ /
\ /
C
我没有在标准中看到另一个地方指定虽然 V
在 C
下面的类层次结构中出现了两次,但只有一个 V 类型的子对象
实际存在是因为使用了 virtual
关键字。
关于具有混合虚拟和非虚拟基础的 C++11 类格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16886788/