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

在观察结果之后,一种可能的解决方案是让每个派生类都有自己的分配器。我不明白。如果基类有分配器,为什么派生类仍然使用基类的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 回答