Question

En raison d'un problème que je rencontre, est-il possible de créer un vecteur de pointeurs? Et si oui, comment? Spécifiquement concernant l’utilisation des itérateurs et .begin () avec elle, c’est-à-dire: Comment puis-je transformer ce vecteur en un vecteur de pointeurs:

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();
}
Était-ce utile?

La solution 2

vector <c> cvect n'est pas un vecteur de pointeurs. C'est un vecteur d'objets de type c. Vous voulez vector <c*> cvect. et vous voulez probablement:

cvect.push_back( new c );

Et puis, étant donné un itérateur, vous voulez quelque chose comme:

(*it)->func();

Bien sûr, il est fort probable que vous ne vouliez pas un vecteur de pointeurs en premier lieu ...

Autres conseils

Bien sûr.

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

Points à garder à l'esprit:

Vous aurez besoin de nettoyer vous-même si vous utilisez de la mémoire allouée dynamiquement comme je l'ai fait dans mon exemple

exemple:

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

Ceci peut être simplifié en utilisant un vecteur de shared_ptr s (comme boost::shared_ptr). N'essayez pas d'utiliser std::auto_ptr pour cela, cela ne fonctionnera pas (ne sera même pas compilé).

Une autre chose à garder à l'esprit, vous devriez éviter d'utiliser < pour comparer les itérateurs de votre boucle lorsque cela est possible; cela ne fonctionnera que pour les itérateurs qui modélisent un itérateur à accès aléatoire, ce qui signifie que vous ne pouvez pas modifier votre code en utiliser par exemple a std::list.

Oui, c'est possible, et en fait, il est nécessaire d'utiliser des pointeurs si vous souhaitez que votre vecteur contienne des objets provenant d'une hiérarchie de classes complète plutôt que d'un seul type. (Ne pas utiliser les pointeurs entraînera le problème redouté du découpage d'objet - tous les objets sont silencieux. converti en type de classe de base, ce qui n’est pas diagnostiqué par le compilateur et n’est certainement pas ce que vous voulez.)

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

Notez qu'avec un vecteur de pointeurs, vous devez gérer vous-même la mémoire , soyez donc très prudent: si vous utilisez des objets locaux (comme ci-dessus), ils ne doivent pas tomber de la portée avant le conteneur fait. Si vous utilisez des pointeurs sur des objets créés avec new, vous devez les delete manuellement avant que le conteneur ne soit détruit. Dans ce cas, vous devez absolument envisager d'utiliser des pointeurs intelligents, tels que le smart_ptr fourni par Boost .

Oui, bien sûr.

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

Veuillez noter la déclaration de vector<c*> cvect et l'utilisation de cvect.push_back(&cobj).

À partir du code fourni, vous utilisez l’itérateur de manière erronée. Pour accéder au membre pointé par un itérateur, vous devez utiliser *citer au lieu de citer seul.

Vous avez créé vector<c*> pour un vecteur de pointeurs. Utilisez ensuite new pour allouer la mémoire pour les objets c et les insérer dans un vecteur. De plus, n'oubliez pas que vous devez delete vous-même et que vector.clear () ne libérera pas la mémoire allouée pour les objets c. Vous devez stocker c en tant que vecteur de pointeurs ici, sinon l'appel à la fonction virtuelle ne fonctionnera pas.

Essayez Bibliothèque de conteneurs Boost Pointer . Il présente plusieurs avantages par rapport au vecteur de pointeurs habituel, tel que:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top