É possível criar um vetor de ponteiros?
-
03-07-2019 - |
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();
}
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_ptr
s (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