3

基本的なメンバーと関数を持つクラス A があります。

class A{
public:
    typedef struct{
        int aa;
        int bb;
    } stEntry;
    stEntry entry;

    void function1();
    void function2();
};

構造stEntryを含むクラスAを拡張する必要があるクラスBより...

class B : public A{
public:
    typedef struct :stEntry
    {
        int cc;
    } stEntry;
    stEntry entry;

    void function3();
};

その後:

int main() {
    A a;
    B b;
    a.entry.aa = 1;    
    b.entry.aa = 2;
    b.entry.cc = 3;

    cout << "class A:"<<sizeof(a)<< endl;
    cout << "class B:"<<sizeof(b)<< endl;

    return 0;
}

私は得る

class A:8
class B:20

したがって、クラス B には 2 つのインスタンス (8 バイト (A クラス メンバー) + 12 バイト (B クラス メンバー)) が含まれます。

クラス B の構造 stEntry を拡張する方法はありますか? (2つのインスタンスがない場合)

4

2 に答える 2

4

いいえ、2 つのインスタンスを自分で作成しているためです。基本クラスにはインスタンスがあり、派生クラスには (基本クラスの内部クラスを拡張するクラスの) インスタンスがあります。

それ以外の基本クラスの構造を変更することはできません。一度定義すると、そのまま残ります。

于 2013-01-22T14:15:02.970 に答える
2

並べ替え、仮想継承:

struct stEntryBase {
    int aa;
    int bb;
};

struct A : virtual stEntryBase {
    typedef stEntryBase stEntry;

    void function1();
    void function2();
};

struct stEntryDerived : virtual stEntryBase {
    int cc;
};

struct B : A, stEntryDerived {
    typedef stEntryDerived stEntry;

    void function3();
};

別のレベルの継承に進みたい場合は、B実質的に から派生しstEntryDerivedます。

a.aaここで、フィールドを として参照する必要があります。b.ccメンバーはありませんentry。また、stEntry型は POD ではなくなりました (そのためbb、 とccがメモリ内で隣接しなくなる可能性があります)。最後に、仮想継承によるサイズの増加は、実際には 2 より大きい場合がありintます。

できることは、のインスタンスからstEntryDerived*またはを取得することです。次に、そのポインター/参照を使用して、 、 、および のメンバーとしてアクセスできます。ユーザーはについて知る必要はありません。したがって、いくらかのコストでインターフェースの分離を達成しました。stEntryDerived&BaabbccstEntryDerivedB

于 2013-01-22T14:27:17.957 に答える