2

ポリモーフィズムの側面について混乱しています。次のコードを検討してください。

#include <iostream>

class CBase {
    virtual void dummy() {}
};
class CDerived: public CBase {
    public:
    int a,b,c,d;
    CDerived (): a(1),b(2),c(3),d(4) { }
};
int main () {

    CBase* pba = new CDerived;

    std::cout << "sizeof(CBase) = " << sizeof(CBase) << std::endl; // prints 8
    std::cout << "sizeof(CDerived) = " << sizeof(CDerived) << std::endl; // prints 24

    std::cout << "sizeof(*pba) = " << sizeof(*pba) << std::endl; // prints 8 (?)

    return 0;
}

私の質問は次のとおりです。ラインでは、タイプ(24バイト)CBase* pba = new CDerived;のオブジェクトCDerivedが割り当てられていますが、ご覧のとおり、sizeof(*pba) = 8バイトです。CDerivedが指すオブジェクトの残りの 16 バイトはどうなりましたpbaか? 私もこれを試しました:

std::cout << "pba->a = " << pba->a << std::endl;

しかし、コンパイルエラーが発生しました。つまり、pba実際には type のオブジェクトを指していませんCDerived。それで、ここで何が起こったのですか?メモリーリーク?

4

2 に答える 2

10

sizeofコンパイル時の構造です。実行時の型を認識できないため、コンパイル時の型のみを考慮しますCBase&

pba->aは同様の理由でコンパイルされません: のコンパイル時の型はpbaであり、メンバをCBase*持ちCBaseません。aこれが静的型付け言語の仕組みです。CDerivedメンバーを使用する場合は、型を持つ変数CDerived(またはそれへの参照またはポインター) が必要です。

ただし、オブジェクトCDerivedはまだそこにあります。CDerivedのように、ポインターを へのポインターに変換すると、それがわかりますdynamic_cast<CDerived*>(pba)->a

于 2012-08-29T12:28:55.527 に答える
0

sizeofオブジェクトの静的型のサイズを返します。pbaは であるためCBase*、 の静的型は で*pbaありCBase、そのサイズは8(データ メンバーなしでvfptr) です。\

[...] pba が実際にはタイプ CDerived のオブジェクトを指していないことを意味します

CDerivedただし、へのポインターを介して特定のメンバーにアクセスすることはできませんCBase

私があなたに a を渡してCBase*、 member にアクセスするように言ったとしますa。できません。CDerivedそれが a へのポインターであり、そのメンバーを持っているか、または他の派生クラスへのポインターであることを確認することはできません(RTTI を使用しない限り)。基本クラス ポインターを介して派生クラス メンバーにアクセスすることは、論理的に意味がありません。

于 2012-08-29T12:28:54.547 に答える