2013-06-02 18 views
7
C++ 11で

(N3485)10.1.4 [class.mi]それは言う:ほとんどの派生クラスのクラス格子における非仮想基底クラスの各別個の出現について仮想ベースと非仮想ベースが混在するC++ 11クラスの格子?

を最も派生したオブジェクトは、対応する基本クラスのサブオブジェクトをそのタイプのものとする。 仮想を指定された各個別の基底クラスの

、ほとんどの派生クラスは、そのタイプの単一基本クラスのオブジェクトを含まなければなりません。

struct B {}; 

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

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

struct D : C1, C2 {}; 

まず、明確にするために、Dのクラス格子がどのように多くの頂点を持っています:

は、以下のC++ 11のコードを検討しますか

第2に、タイプBのいくつかの異なるサブオブジェクトでは、タイプDの最も派生したオブジェクトに標準が必要ですか?

更新:

以下のクラスの格子のですか?

(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)の場合、クラス格子内にクラスが1つしか存在しないため、標準では言語が正しくありませんか?

+0

1. 10の頂点があります。2. 2つの非仮想Bと1つの仮想Bがあります。 –

+0

@fatih_k:10にどのように到着しましたか? –

+0

DからCには2つの頂点、C1からBの2、C2からBの2まであり、仮想Bへの2つのBV 'と1つの頂点とBNからBへの2つの頂点があります。 –

答えて

3

次のうちクラス格子はどれですか?

デモンストレーション:

#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 

それがある場合(2)各出現のために」と言うのに十分ではありませんクラス格子内の 基本クラスの対応する基本クラスがある サブオブジェクト "?つまり、すでに格子の構成が の仮想と非仮想基本クラスの関係に依存している場合は、 のエッジと頂点を選択しますか?

あなたの提案をマージ...

仮想キーワードを含む基本クラス指定子は、 は仮想基本クラスを指定します。最も派生クラスのクラス格子 非仮想基底クラスの各別個 発生するため、ほとんどの派生オブジェクト(1.8) はを含まなければならない対応 異なる基本クラスサブオブジェクトがありますそのタイプのバーチャルに指定された別個の 基本クラスごとに、最も派生したオブジェクトは、そのタイプの単一の基本クラスサブオブジェクトを含むものとする( )。

私は標準の半分の言語の専門家ではありません。図4の

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

結果::私はあなたの変更仕様を読んだときしかし、私はどのように表示されていない、私が指定し、標準で別の場所が表示されていない

V 
/\ 
/ \ 
A  B 
\ /
    \/
    C 

そのV表示されますがC以下のクラス階層で2回使用されると、タイプのサブオブジェクトは、virtualというキーワードを使用するため実際に存在します。

+1

私は(2)が_subobject_ latticeであることに同意するが、 _class_ latticeが(1)または(2)の場合 –

+0

@ user1131467 'subobject lattice'と' class lattice'という用語を明確にすることができますか?これまでこのコンテキストで使用されていたlatticeという言葉は聞いたことがありません。コメント –

+0

@マークB:明確な定義は、私たちが明確にしようとしているものです。これらの用語はどちらもC++標準の10.1節で使用されていますが、その定義は少し曖昧です –

関連する問題