Pergunta

armazenar objetos no vetor heterogêneo com objetos alocados-stack

Olá,

dizer que tenho uma CA classe abstrata, derivado em CA1, CA2, e talvez outros.

Eu quero colocar objetos desses tipos derivados em um vetor, que eu embbed em uma CB classe. Para obter polimorfismo direito, eu preciso armazenar um vetor de ponteiros:

class CB
{
    std::vector <CA*> v;
};

Agora, dizer que tenho a seguinte função principal:

int main()
{
    CB b;
    CA1 a1;
    CA2 a2;
    b.Store( a1 );
    b.Store( a2 );
}

Como faço para escrever o void CB::Store(const CA&) método de uma forma simples, de modo que os objetos armazenados sobreviver quando os objetos originais é destruído (o que não ocorre no exemplo simples acima).

O meu problema é que eu preciso primeiros objetos de cópia na pilha antes de copiar o seu endereço no vector, mas como eu posso criar um objeto de um tipo derivado? Claro, eu poderia usar RTTI, e procurar todos os tipos possíveis, criar e atribuir um ponteiro, e copiar (com carcaça adequada) o objeto no espaço alocado antes de empurrá-lo para o vector. Mas isso parece muito complicado, não?

Existe uma maneira mais simples?

(E sem usar a alocação dinâmica no! Principal)

Foi útil?

Solução

Geralmente, você irá fornecer uma função de clone: ??

struct CA
{
    virtual CA *clone(void) const = 0;
    virtual ~CA() {} // And so on for base classes.
}

struct CA1 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA1(*this);
    }
}

struct CA2 : public CA
{
    virtual CA *clone(void) const
    {
        return new CA2(*this);
    }
}

Isto é chamado um virtual construtor , você pode construto cópias de objetos em tempo de execução:

void CB::Store(const CA& pObject)
{
    CA *cloned = pObject.clone();
}

Você deve considerar o uso do Boost.Pointer Container biblioteca . Seu código seria:

boost::ptr_vector<CA> objects;

void CB::Store(const CA& pObject)
{
    objects.push_back(pObject->clone());
}

E agora você não tem nenhuma necessidade de gerenciar a memória sozinho. A biblioteca também respeita funções clone, e vai chamá-lo ao fazer cópias de seus objetos. Tutorial aqui .

Outras dicas

Parece que você precisa de uma função clone () em sua classe abstrata que suas classes derivadas irá implementar.

class CA
{
   public:
   virtual ~CA() {}
   virtual CA* clone() const = 0;
}

class CA1 : public CA
{ 
    public:
    virtual CA *clone() const
    {
       return new CA1(*this);
    }
};

Uma possibilidade seria templatize loja do tipo de seu argumento:

class CB
{
public:
    template<class T>
    void Store(const T& t)
    {
         v.push_back(new T(t));
    }

private:
    std::vector <CA*> v;
};

Um aviso: Ao contrário do "clone ()" solução publicado por outros, este é propenso a cortar. Por exemplo, esta multa funciona:

CB b;
CA1 a1;
CA2 a2;
b.Store(a1);
b.Store(a2);

Mas isso não:

CA1 a1;
CA* a = &a1;
b.Store(*a); //Ouch! this creates a new CA, not a CA1

Dar um ctor cópia protegida para CA impede tal utilização abusiva. No entanto, se ainda CA1 subclasse, a questão volta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top