Pergunta

Basta saber, por causa de um problema que eu estou correndo em, é possível criar um vetor de ponteiros? E se sim, como? Especificamente quanto usando iteradores e .begin () com ele, isto é: Como eu iria transformar este vetor em um vetor de ponteiros:

class c
{
     void virtual func();
};

class sc:public c
{
     void func(){cout<<"using func";}
};

sc cobj;

vector<c>cvect
cvect.push_back(cobj);
vector<c>::iterator citer

for(citer=cvect.begin();citer<cvect.end();citer++)
{
     citer->func();
}
Foi útil?

Solução 2

vector <c> cvect não é um vetor de ponteiros. É um vector de objectos do tipo c. Você quer vector <c*> cvect. e você provavelmente vai querer:

cvect.push_back( new c );

E, em seguida, dado um iterador, você quer algo como:

(*it)->func();

É claro, é bastante provável que você não queria um vetor de ponteiros em primeiro lugar ...

Outras dicas

Claro.

vector<c*> cvect;
cvect.push_back(new sc);
vector<c*>::iterator citer;
for(citer=cvect.begin(); citer != cvect.end(); citer++) {
  (*citer)->func();
}

Coisas para manter em mente:

Você vai precisar de limpeza após a sua auto se você usar a memória alocada dinamicamente como eu fiz no meu exemplo

por exemplo:.

 for(...) { delete *i; }

Isto pode ser simplificada usando um vetor de shared_ptrs (como boost::shared_ptr). Não tente usar std::auto_ptr para isso, não vai funcionar (não vai mesmo compilar).

Outra coisa a ter em mente, você deve evitar usar < para comparar iterators em seu loop quando possível, ela só vai trabalho para iterators esse modelo um iterador de acesso aleatório, o que significa que você não pode mudar o seu código para usar por exemplo um std::list.

Sim, é possível, e na verdade é necessário usar ponteiros se você pretende seu vetor para conter objetos de uma hierarquia de classe inteira em vez de de um único tipo. (Deixar de usar ponteiros irá resultar no problema temido de objeto corte - todos os objetos são silenciosamente convertidos para o tipo de classe base. Esta não é diagnosticado pelo compilador, e quase certamente não é o que você quer.)

class c
{
     void virtual func();
};

class sc:public c
{
     void func(){cout<<"using func";}
};

sc cobj;

vector<c*> cvect;             // Note the type is "c*"
cvect.push_back(&cobj);       // Note the "&"
vector<c*>::iterator citer;

for(citer=cvect.begin();citer != cvect.end();citer++)   // Use "!=" not "<"
{
     (*citer)->func();
}

Note que, com um vetor de ponteiros, que você precisa fazer seu próprio gerenciamento de memória , que deve ter muito cuidado - se você estará usando objetos locais (como acima), não devem cair do escopo antes do recipiente faz. Se você usar ponteiros para objetos criados com new, você precisa delete-los manualmente antes de o recipiente é destruído. Você deve absolutamente considerar o uso de ponteiros inteligentes, neste caso, como o smart_ptr fornecidos pela Boost .

Sim, claro.

// TestCPP.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <vector>


using namespace std;

class c
{
public:
    void virtual func() = 0;
};

class sc:public c
{
public:
    void func(){cout<<"using func";}
};

int _tmain(int argc, _TCHAR* argv[])
{
    sc cobj;

    vector<c*> cvect;
    cvect.push_back(&cobj);
    vector<c*>::iterator citer;

    for(citer=cvect.begin();citer<cvect.end();citer++)
    {
        (*citer)->func();
    }

    return 0;
}

Por favor, note a declaração de vector<c*> cvect eo uso de cvect.push_back(&cobj).

A partir do código fornecido, você está usando iterador de uma maneira errada. Para acessar o membro um iterador está apontando para você deve usar *citer vez de citer sozinho.

Você tem criar vector<c*> para um vetor de ponteiros. Em seguida, use new para alocar a memória para objetos C e empurrá-los para vetor. Além disso, não se esqueça que você tem que delete si mesmo e vector.clear () não vai liberar a memória alocada para objetos C. Você tem que armazenar c como um vetor de ponteiros aqui, caso contrário, a chamada para a função virtual não vai funcionar.

Tente impulso Pointer Container Biblioteca . Ele tem várias vantagens sobre vector regular de ponteiros, como:

my_container.push_back( 0 );            // throws bad_ptr 
ptr_vector<X> pvec; 
std::vector<X*> vec;
( *vec.begin() )->foo(); // call X::foo(), a bit clumsy
pvec.begin()->foo();     // no indirection needed
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top