Is it possible to create a vector of pointers?

30,590

Solution 1

vector <c> cvect is not a vector of pointers. It is a vector of objects of type c. You want vector <c*> cvect. and the you probably want:

cvect.push_back( new c );

And then, given an iterator, you want something like:

(*it)->func();

Of course, it's quite probable you didn't want a vector of pointers in the first place...

Solution 2

Sure.

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

Things to keep in mind:

You'll need to cleanup after your self if you use dynamically allocated memory as I did in my example

e.g.:

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

This can be simplified by using a vector of shared_ptrs (like boost::shared_ptr). Do not attempt to use std::auto_ptr for this, it will not work (won't even compile).

Another thing to keep in mind, you should avoid using < to compare iterators in your loop when possible, it will only work for iterators that model a random access iterator, which means you can't change out your code to use e.g. a std::list.

Solution 3

Yes it is possible, and in fact it is necessary to use pointers if you intend your vector to contain objects from an entire class hierarchy rather than of a single type. (Failing to use pointers will result in the dreaded problem of object slicing -- all objects are silently converted to base class type. This is not diagnosed by the compiler, and is almost certainly not what you want.)

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 that with a vector of pointers, you need to do your own memory management, so be very careful -- if you will be using local objects (as above), they must not fall out of scope before the container does. If you use pointers to objects created with new, you'll need to delete them manually before the container is destroyed. You should absolutely consider using smart pointers in this case, such as the smart_ptr provided by Boost.

Solution 4

You have create vector<c*> for a vector of pointers. Then use new to allocate the memory for c objects and push them into vector. Also, don't forget that you have to delete yourself and vector.clear() will not release the memory allocated for c objects. You have to store c as a vector of pointers here, otherwise the call to the virtual function will not work.

Solution 5

Yes, sure.

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

Please note the declaration of vector<c*> cvect and the use of cvect.push_back(&cobj).

From the code provided, you are using iterator in a wrong way. To access the member an iterator is pointing to you must use *citer instead of citer alone.

Share:
30,590
Admin
Author by

Admin

Updated on May 05, 2020

Comments

  • Admin
    Admin about 4 years

    Just wondering, because of a problem I am running into, is it possible to create a vector of pointers? And if so, how? Specifically concerning using iterators and .begin() with it, ie: How would I turn this vector into a vector of pointers:

    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();
    }
    
  • Kiran Kumar
    Kiran Kumar about 15 years
    func() is a virtual function, so I guess vector of pointers is required here.
  • bk1e
    bk1e about 15 years
    And if push_back() throws, you probably want to avoid leaking the new c.