0

基本クラスから派生した (または基本クラスである) 指定されたポインター型の別のオブジェクトを割り当てる必要があると思います。

たとえば、このクラス CChunk と、その派生クラス CMODChunk があります。

CChunk (CChunk、CMODChunk、またはその他の派生物である可能性があります) へのポインターを渡す関数で、その特定の型の別のオブジェクトを割り当てることができるようにしたいと考えています。それでおしまい。基本的に、ポインタが指している型を知りたいです。

typeof、typeid、および仮想についてもう少し理解するために、非常に長いテストコードを作成しました...

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>
using namespace std;

class base_virtual
    {
    public:
    base_virtual ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        }
    virtual void dummy( void )
        {
        }
    base_virtual *Alloc ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        return new typeof (*this);
        };
    void GetTypeInfo()
        {
        printf("%sname %s\n",__PRETTY_FUNCTION__, typeid( *this).name());
        }
    };

class der_virtual_1: public base_virtual
    {
    public:
    der_virtual_1 ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        }
    base_virtual *Alloc ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        return new typeof (*this);
        };
    };

class der_virtual_2 : public base_virtual
    {
    public:
    der_virtual_2 ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        }
    };

class base
    {
    public:
    base ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        }
    void dummy( void )
        {
        }
    base *Alloc ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        return new typeof (*this);
        };
    void GetTypeInfo()
        {
        printf("%s %s\n",__PRETTY_FUNCTION__, typeid( *this).name());
        }
    };

class der_1 : public base
    {
    public:
    der_1 ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        }
    base *Alloc ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        return new typeof (*this);
        };
    };

class der_2 : public base
    {
    public:
    der_2 ( void )
        {
        printf("%s\n",__PRETTY_FUNCTION__);
        }
    };

int main ( int argc, char *argv[] )
    {
    printf("\n\n%s Criacao de objectos\n",__PRETTY_FUNCTION__);
    printf("\n");
    printf("%s base virtual\n",__PRETTY_FUNCTION__);
    base_virtual bv1;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bv1).name());
    bv1.GetTypeInfo();

    printf("%s base nao virtual\n",__PRETTY_FUNCTION__);
    base b1;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(b1).name());
    b1.GetTypeInfo();

    printf("\n");
    printf("%s derivado 1 virtual\n",__PRETTY_FUNCTION__);
    der_virtual_1 dv1;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(dv1).name());
    dv1.GetTypeInfo();
    printf("%s derivado 1 nao virtual\n",__PRETTY_FUNCTION__);
    der_1 d1;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(d1).name());
    d1.GetTypeInfo();

    printf("\n");
    printf("%s derivado 2 virtual\n",__PRETTY_FUNCTION__);
    der_virtual_2 dv2;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(dv2).name());
    dv2.GetTypeInfo();
    printf("%s derivado 2 nao virtual\n",__PRETTY_FUNCTION__);
    der_2 d2;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(d2).name());
    d2.GetTypeInfo();

    base_virtual *bvpointer;
    base *bpointer;

    printf("\n\n%s Alocacao explicita\n",__PRETTY_FUNCTION__);
    printf("\n");
    printf("%s base virtual\n", __PRETTY_FUNCTION__);
    bvpointer = new base_virtual;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s base nao virtual\n", __PRETTY_FUNCTION__);
    bpointer = new base;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;

    printf("\n");
    printf("%s derivado 1 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = new der_virtual_1;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 1 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = new der_1;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;

    printf("\n");
    printf("%s derivado 2 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = new der_virtual_2;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 2 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = new der_2;
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;


    printf("\n\n%s Alocacao explicita com typeof tipo\n",__PRETTY_FUNCTION__);
    printf("\n");
    printf("%s base virtual\n", __PRETTY_FUNCTION__);
    bvpointer = new typeof (base_virtual);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s base nao virtual\n", __PRETTY_FUNCTION__);
    bpointer = new typeof (base);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;

    printf("\n");
    printf("%s derivado 1 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = new typeof (der_virtual_1);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 1 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = new typeof (der_1);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;

    printf("\n");
    printf("%s derivado 2 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = new typeof (der_virtual_2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 2 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = new typeof (der_2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;

    printf("\n\n%s Alocacao explicita com typeof pointer\n",__PRETTY_FUNCTION__);
    base_virtual *bvpointer2;
    base *bpointer2;
    bvpointer2=new base_virtual;
    bpointer2 = new base;
    printf("\n");
    printf("%s base virtual\n", __PRETTY_FUNCTION__);
    bvpointer = new typeof (*bvpointer2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s base nao virtual\n", __PRETTY_FUNCTION__);
    bpointer = new typeof (*bpointer2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;
    delete bvpointer2;
    delete bpointer2;

    bvpointer2=new der_virtual_1;
    bpointer2 = new der_1;
    printf("\n");
    printf("%s derivado 1 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = new typeof (*bvpointer2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 1 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = new typeof (*bpointer2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;
    delete bvpointer2;
    delete bpointer2;

    bvpointer2=new der_virtual_2;
    bpointer2 = new der_2;
    printf("\n");
    printf("%s derivado 2 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = new typeof (*bvpointer2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 2 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = new typeof (*bpointer2);
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;
    delete bvpointer2;
    delete bpointer2;


    printf("\n\n%s Alocacao implicita com funcao\n",__PRETTY_FUNCTION__);
    printf("\n");
    printf("%s base virtual\n", __PRETTY_FUNCTION__);
    bvpointer = bv1.Alloc();
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s base nao virtual\n", __PRETTY_FUNCTION__);
    bpointer = b1.Alloc();
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;

    printf("\n");
    printf("%s derivado 1 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = dv1.Alloc();
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 1 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = d1.Alloc();
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;

    printf("\n");
    printf("%s derivado 2 virtual\n",__PRETTY_FUNCTION__);
    bvpointer = dv2.Alloc();
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bvpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bvpointer).name());
    bvpointer->GetTypeInfo();
    delete bvpointer;
    printf("%s derivado 2 nao virtual\n",__PRETTY_FUNCTION__);
    bpointer = d2.Alloc();
    printf ("%s typeid %s\n", __PRETTY_FUNCTION__, typeid(bpointer).name());
    printf ("%s typeid * %s\n", __PRETTY_FUNCTION__, typeid(*bpointer).name());
    bpointer->GetTypeInfo();
    delete bpointer;
    return 0;
    }

この結果を見た後、考えられる解決策の 1 つは、すべての派生クラスに独自の Allocator を持たせることです。わかりません。基本クラスにアロケーターがある場合、なぜ派生クラスは派生クラスからではなく基本から typeof を使用するのですか?

4

1 に答える 1

1

通常の方法は、(共変?)clone()関数を提供することです。

struct Base
{
    virtual Base * clone()  { return new Base(*this); }
    virtual ~Base() { }
};

struct Derived : Base
{
    virtual Derived * clone() { return new Derived(*this); }   // this is an override
};

次に、次のように言うことができます。

Base * p = get();
Base * q = p->clone();
于 2012-05-30T17:27:17.570 に答える