C++11 class lattice with mixed virtual and non

In C++11 (N3485) 10.1.4 [class.mi] it says:

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.

Consider the following C++11 code:

struct B {};

struct BV : virtual B {};
struct BN : B {};

struct C1 : BV, BN {};
struct C2 : BV, BN {};

struct D : C1, C2 {};

Firstly, for clarity, how many vertices does the class lattice of D have?

Secondly, how many distinct subobjects of type B does the standard require that a most derived object of type D have?

update:

Which of the following is the class lattice?

(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

If the intention is that it is (1) then isn't it impossible to have any DAG that isn't a tree? (ie a diamond is impossible) If so wouldn't it be better to call it the class tree?

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?

If it is (3) then isn't the language incorrect in the standard because there can only ever be one occurence of a class in the class lattice?


Which of the following is the class lattice?

2

Demonstration:

#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';
}

My output:

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?

Merging your suggestion...

A base class specifier that contains the keyword virtual , specifies a virtual base class. For each distinct occurrence of a non-virtual base class in the class lattice of the most derived class, the most derived object (1.8) shall contain there is a corresponding distinct base class subobject of 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.

I'm not an expert in the language half of the standard. However when I read your modified specification, I don't see how:

class V { /∗...∗/ };
class A : virtual public V { /∗ ... ∗/ };
class B : virtual public V { /∗ ... ∗/ };
class C : public A, public B { /∗...∗/ };

Results in Figure 4:

   V
  / 
 /   
A     B
    /
   /
   C

I don't see another place in the standard that specifies that although V appears twice in the class hierarchy below C , only one subobject of type V actually exists because of the use of the virtual keyword.

链接地址: http://www.djcxy.com/p/13840.html

上一篇: 带重复参数的磁铁模式(可变参数)

下一篇: 具有混合虚拟和非混合的C ++ 11类格