Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Store pointers in a vector?

Reply
Thread Tools

Store pointers in a vector?

 
 
Roland Bengtsson
Guest
Posts: n/a
 
      12-19-2003
I have a class Conception and I have this in a vector, it should be:

vector<Conception> vek; // vector
vector<Conception>::iterator vek; // iterator to vek

But what if I want to have pointers to class Conception instead? How
can I do that? And how should I write to declare an iterator to this
vector?
 
Reply With Quote
 
 
 
 
Jeremy Cowles
Guest
Posts: n/a
 
      12-19-2003
"Roland Bengtsson" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> I have a class Conception and I have this in a vector, it should be:
>
> vector<Conception> vek; // vector
> vector<Conception>::iterator vek; // iterator to vek
>
> But what if I want to have pointers to class Conception instead? How
> can I do that? And how should I write to declare an iterator to this
> vector?


I am just moving to C++, so this may be wrong, but isn't a pointer just a
data type like anything else? I would think you could declare it like this:

vector<Conception*> vek; // vector

No?

Jeremy

 
Reply With Quote
 
 
 
 
Jeffrey Schwab
Guest
Posts: n/a
 
      12-19-2003
Jeremy Cowles wrote:
> "Roland Bengtsson" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
>
>>I have a class Conception and I have this in a vector, it should be:
>>
>>vector<Conception> vek; // vector
>>vector<Conception>::iterator vek; // iterator to vek
>>
>>But what if I want to have pointers to class Conception instead? How
>>can I do that? And how should I write to declare an iterator to this
>>vector?

>
>
> I am just moving to C++, so this may be wrong, but isn't a pointer just a
> data type like anything else? I would think you could declare it like this:
>
> vector<Conception*> vek; // vector
>
> No?
>
> Jeremy
>


Right, but make sure you've declared vector, and that you're looking in
the right namespace for it:

#include <vector>

int main( )
{
std::vector<Conception*> vek; // useless comment
}

 
Reply With Quote
 
Jeffrey Schwab
Guest
Posts: n/a
 
      12-19-2003
Jeffrey Schwab wrote:
> Jeremy Cowles wrote:
>
>> "Roland Bengtsson" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed) om...
>>
>>> I have a class Conception and I have this in a vector, it should be:
>>>
>>> vector<Conception> vek; // vector
>>> vector<Conception>::iterator vek; // iterator to vek
>>>
>>> But what if I want to have pointers to class Conception instead? How
>>> can I do that? And how should I write to declare an iterator to this
>>> vector?

>>
>>
>>
>> I am just moving to C++, so this may be wrong, but isn't a pointer just a
>> data type like anything else? I would think you could declare it like
>> this:
>>
>> vector<Conception*> vek; // vector
>>
>> No?
>>
>> Jeremy
>>

>
> Right, but make sure you've declared vector, and that you're looking in
> the right namespace for it:
>
> #include <vector>
>
> int main( )
> {
> std::vector<Conception*> vek; // useless comment


Whoops! That should be:

class Conception;

std::vector<Conception*> vek; // useless comment

> }
>


 
Reply With Quote
 
Mike Wahler
Guest
Posts: n/a
 
      12-19-2003
"Roland Bengtsson" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> I have a class Conception and I have this in a vector, it should be:
>
> vector<Conception> vek; // vector
> vector<Conception>::iterator vek; // iterator to vek


You have the same name ('vek') for two different objects!

>
> But what if I want to have pointers to class Conception instead?


No problem.

> How
> can I do that?


Same way you specify any other type element.

vector<Conception *> vek;

>And how should I write to declare an iterator to this
> vector?


vector<Conception *>::iterator vi;

Of course now you're responsible for managing any memory pointed
to by your pointers.

-Mike


 
Reply With Quote
 
Roland Bengtsson
Guest
Posts: n/a
 
      12-20-2003
More code here may clarify!
Now I have this compiler error:
main.cpp(37) : error C2679: binary '=' : no operator defined which
takes a right-hand operand of type 'class std::list<class Conception,
class std::allocator<class Conception> >::iterator' (or there is no
acceptable conversion)

#include <iostream>
#include <vector>
#include <list>
using namespace std;

class Conception
{
public:
Conception();
virtual ~Conception();

char *name; // the classen contains more than this...
};

void ListConcept(list &ConceptList);

void main()
{
list CList;

ListConcept(CList);
}

void ListConcept(list &ConceptList)
{
// 1. Declare a list with Conception
list::iterator It_Print;
// 2. Declare a vector with pointers to Conceptions
vector SortPage(ConceptList.size());
// 3. Declare an iterator to go through nr 2.
vector::iterator it_SortPage;

// This loop fills SortPage vector with pointers to Conceptions in
// declaration 1.
for(It_Print = ConceptList.begin();It_Print !=
ConceptList.end();It_Print++)
{
*it_SortPage = It_Print; // What should be here???
it_SortPage++;
}
}
 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      12-20-2003
Roland Bengtsson wrote:

> More code here may clarify!
> Now I have this compiler error:
> main.cpp(37) : error C2679: binary '=' : no operator defined which
> takes a right-hand operand of type 'class std::list<class Conception,
> class std::allocator<class Conception> >::iterator' (or there is no
> acceptable conversion)
>
> #include <iostream>
> #include <vector>
> #include <list>
> using namespace std;
>
> class Conception
> {
> public:
> Conception();
> virtual ~Conception();
>
> char *name; // the classen contains more than this...
> };
>
> void ListConcept(list &ConceptList);


ConceptList doesn't have a type, since list is the name of a template,
not of a type. You must specify the template parameters, like:

void ListConcept(list<Conception*> &ConceptList);

I assume you want that, since you asked how to define a container of
pointers to Conception.

> void main()



main() _must_ return int. Nothing else. Never!

> {
> list CList;
>
> ListConcept(CList);
> }
>
> void ListConcept(list &ConceptList)


void ListConcept(list<Concept*> &ConceptList)

> {
> // 1. Declare a list with Conception
> list::iterator It_Print;


list<Concept*>::iteraotr It_Print;

> // 2. Declare a vector with pointers to Conceptions
> vector SortPage(ConceptList.size());


vector<Concept*> SortPage(ConceptList.size());

> // 3. Declare an iterator to go through nr 2.
> vector::iterator it_SortPage;


vector<Concept*>::iterator it_SortPage;

> // This loop fills SortPage vector with pointers to Conceptions in
> // declaration 1.
> for(It_Print = ConceptList.begin();It_Print !=
> ConceptList.end();It_Print++)
> {
> *it_SortPage = It_Print; // What should be here???


It_Print is an iterator to Concept*, *it_SortPage is a Concept*. That
doesn't match. Write:

*it_SortPage = *It_Print;

> it_SortPage++;
> }
> }


Uhm, I assume your function actually does a bit more, because as it is
now, it copies the container and then destroys the copy without doing
anything with it. You also don't seem to modify the list, so your
function should take a const reference to it.
Btw, you could make your function a lot shorter by using std::copy from
<algorithm>:

void ListConcept(list<Concept*> &ConceptList)
{
vector<Concept*> SortPage;
SortPage.reserve(ConceptList.size());
std::copy(ConceptList.begin(), ConceptList.end(),
std::back_inserter(SortPage));

//the rest, whatever it is supposed to do
}

 
Reply With Quote
 
Roland Bengtsson
Guest
Posts: n/a
 
      12-21-2003
> > void ListConcept(list &ConceptList);
>
> ConceptList doesn't have a type, since list is the name of a template,
> not of a type. You must specify the template parameters, like:
>
> void ListConcept(list<Conception*> &ConceptList);
>
> I assume you want that, since you asked how to define a container of
> pointers to Conception.


But the list stores not pointers to Conceptions, they store the whole
Conception

void ListConcept(list<Conception> &ConceptList)

A reference is passed to ListConcept()

> > void main()

>
>
> main() _must_ return int. Nothing else. Never!


Ok, but I have heared that the compiler put a return 0; in the end of
main() if the type is void. And this is ansi standard now.

> Uhm, I assume your function actually does a bit more, because as it is
> now, it copies the container and then destroys the copy without doing
> anything with it. You also don't seem to modify the list, so your
> function should take a const reference to it.


No, the ListConcept() will sort Conceptions and then list them. The
ConceptList will not be modified. Is this the right prototyp if I use
const?

void ListConcept(const list<Conception> &ConceptList);

> Btw, you could make your function a lot shorter by using std::copy from
> <algorithm>:


This kind of help is always welcome, but I can't compile the code
anymore with this modifications. VC++ says:

include\xutility(19) : error C2679: binary '=' : no operator defined
which takes a right-hand operand of type 'class Conception' (or there
is no acceptable conversion)

I got an error in a standard include-file, I have not a clue what it
is...
Btw, the next step is the sorting, I have two alternatives, use a
functionpointer or a functionoperator. None of these are working

Here are the new code:

#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;

class Conception
{
public:
Conception(int p=0): page(p) {};

void SetPage(int t)
{
page = t;
};

int GetPage()
{
return page;
};
int page; // The class contains more, this is just a testcase
};

// This class is for the sorting
class Conceptionsorter
{
public:
// A functionoperator
int operator() (int pageA, int pageB)
{
return pageA - pageB;
};
};

void ListConcept(list<Conception> &ConceptList);

void main()
{
list<Conception> CList;
Conception A,B,C;

A.SetPage(12);
B.SetPage(7);
C.SetPage(24);

CList.push_back(A);
CList.push_back(B);
CList.push_back(C);

ListConcept(CList);
}


// a simple sort function
int Csort(int pageA, int pageB)
{
return pageA - pageB;
}

void ListConcept(list<Conception> &ConceptList)
{
// 2. Declare a vector with pointers to Conceptions
vector<Conception *> SortPage;
vector<Conception *>::iterator it_SortPage;

SortPage.reserve(ConceptList.size());
std::copy(ConceptList.begin(), ConceptList.end(),
std::back_inserter(SortPage));

// Print all data from the vector, in reality the data is in the
list
for(it_SortPage = SortPage.begin();it_SortPage !=
SortPage.end();it_SortPage++)
cout << (*it_SortPage)->GetPage() << endl;

// Sort the data, I have 2 alternatives
// 1. Give a function as argument
//sort(SortPage.begin(), SortPage.end(),Csort);

// 2. Give a functionobject as argument
//sort(SortPage.begin(), SortPage.end(),Conceptionsorter());
}
 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      12-21-2003
Roland Bengtsson wrote:

>> > void ListConcept(list &ConceptList);

>>
>> ConceptList doesn't have a type, since list is the name of a
>> template, not of a type. You must specify the template parameters,
>> like:
>>
>> void ListConcept(list<Conception*> &ConceptList);
>>
>> I assume you want that, since you asked how to define a container of
>> pointers to Conception.

>
> But the list stores not pointers to Conceptions, they store the whole
> Conception


How should I have known that from your incorrect pseudo code? Please
always post real code to avoid such misunderstandings.

> void ListConcept(list<Conception> &ConceptList)
>
> A reference is passed to ListConcept()
>
>> > void main()

>>
>>
>> main() _must_ return int. Nothing else. Never!

>
> Ok, but I have heared that the compiler put a return 0; in the end of
> main() if the type is void. And this is ansi standard now.


No. A void function doesn't return anything. The C++ standard clearly
says that main must return int. What you are probably referring to is
that you can leave out a return statement in main, which will
implicitly return 0 then. Nevertheless, the return type must still be
int. Note also that this implicit return is an exception that is only
valid for the main() function.

>> Uhm, I assume your function actually does a bit more, because as it
>> is now, it copies the container and then destroys the copy without
>> doing anything with it. You also don't seem to modify the list, so
>> your function should take a const reference to it.

>
> No, the ListConcept() will sort Conceptions and then list them. The
> ConceptList will not be modified.


Ah, now I see what you want.

> Is this the right prototyp if I use
> const?
>
> void ListConcept(const list<Conception> &ConceptList);


Yes.

>> Btw, you could make your function a lot shorter by using std::copy
>> from <algorithm>:

>
> This kind of help is always welcome, but I can't compile the code
> anymore with this modifications.


Well, I was assuming that both containers are supposed to contain
pointers. If one has direct instances, and the other one has pointers,
this will of course not work.

> VC++ says:
>
> include\xutility(19) : error C2679: binary '=' : no operator defined
> which takes a right-hand operand of type 'class Conception' (or there
> is no acceptable conversion)
>
> I got an error in a standard include-file, I have not a clue what it
> is...


This is because the std::copy template tries to assign an instance of
type Conception to a pointer to Conecption, which is not possible. The
error message could be more clear (e.g. by telling the left hand type,
too or the line of your code that was the reason for the assignment).

> Btw, the next step is the sorting, I have two alternatives, use a
> functionpointer or a functionoperator. None of these are working
>
> Here are the new code:
>
> #include <iostream>
> #include <algorithm>
> #include <vector>
> #include <list>
> using namespace std;
>
> class Conception
> {
> public:
> Conception(int p=0): page(p) {};
>
> void SetPage(int t)
> {
> page = t;
> };


You don't need a semicolon after a function definition.

>
> int GetPage()
> {
> return page;
> };
> int page; // The class contains more, this is just a testcase
> };
>
> // This class is for the sorting
> class Conceptionsorter
> {
> public:
> // A functionoperator
> int operator() (int pageA, int pageB)
> {
> return pageA - pageB;
> };
> };


The comparison object is expected to take two objects of the element
type of your container (i.e. pointers to Conception, not int) and
return a bool (true if the first argument is less, false if it's
greater than the other), so change it to:

class Conceptionsorter
{
public:
// A functionoperator
bool operator()(Conception* a, Conception* b) const
{
return a->GetPage() < b->GetPage();
}
};


> void ListConcept(list<Conception> &ConceptList);
>
> void main()
> {
> list<Conception> CList;
> Conception A,B,C;
>
> A.SetPage(12);
> B.SetPage(7);
> C.SetPage(24);
>
> CList.push_back(A);
> CList.push_back(B);
> CList.push_back(C);
>
> ListConcept(CList);
> }
>
>
> // a simple sort function
> int Csort(int pageA, int pageB)
> {
> return pageA - pageB;
> }


You'd need changes similar to those for the function object:

// a simple sort function
bool Csort(Conception* a, Conception* b)
{
return a->GetPage() < b->GetPage();
}

> void ListConcept(list<Conception> &ConceptList)
> {
> // 2. Declare a vector with pointers to Conceptions
> vector<Conception *> SortPage;
> vector<Conception *>::iterator it_SortPage;
>
> SortPage.reserve(ConceptList.size());
> std::copy(ConceptList.begin(), ConceptList.end(),
> std::back_inserter(SortPage));


Well, if one container contains objects and the other one pointers to
them, you'll need either a function object that returns a pointer, or
you have to go back to copying the data yourself. I'd do it something
like this:

vector<Conception *> SortPage;
list<Conception>::iterator it = ConceptList.begin();
list<Conception>::iterator end = ConceptList.end();

SortPage.reserve(ConceptList.size());
for(; it != end; ++it)
SortPage.push_back(&(*it));

*it will be the element to which the iterator points, and then you need
to take that element's address with the & operator and append the
result to the vector.

> // Print all data from the vector, in reality the data is in the
> list
> for(it_SortPage = SortPage.begin();it_SortPage !=
> SortPage.end();it_SortPage++)
> cout << (*it_SortPage)->GetPage() << endl;
>
> // Sort the data, I have 2 alternatives
> // 1. Give a function as argument
> //sort(SortPage.begin(), SortPage.end(),Csort);
>
> // 2. Give a functionobject as argument
> //sort(SortPage.begin(), SortPage.end(),Conceptionsorter());



Those sort() calls should work with the above modifications.

> }


--
Why is lemon juice mostly artificial ingredients but
dishwashing liquid contains real lemons?

 
Reply With Quote
 
Anders Hybertz
Guest
Posts: n/a
 
      12-21-2003
Roland Bengtsson wrote:

> I have a class Conception and I have this in a vector, it should be:
>
> vector<Conception> vek; // vector
> vector<Conception>::iterator vek; // iterator to vek
>
> But what if I want to have pointers to class Conception instead? How
> can I do that? And how should I write to declare an iterator to this
> vector?


The solution might be for you as some other suggest to just just object
pointers, but that opens up a new can of worms.

"Who manages the lifetime of the objects in the vector."

If the aggregated vector goes out of scope your constructor might want
to delete all the object in the vector. Other objects might now have
dangling pointers to objects that has been deleted.

Instead have a look at boost and it's shared pointer implementation. It
introduces reference counted objects, and ensures that you never get
another dangling pointer. And you don't have to worry about destruction
either

The syntax is like

typedef boost::shared_ptr<Conception> ConceptionPtr;
std::vector<ConceptionPtr> ConceptionVector;

// Put new elements in vector
ConceptionVector.push_back( ConceptionPtr( new Conception(...) );

// Use elements in vector
ConceptionVector[42]->ConceptionMemberFunction(...);


// NOTE: Don't worry about destruction. On end of scope, the shared
pointer will call the destructors on all objects that have a ref. count = 0

Hope that helps

/Anders
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
Store pointers to member function in the map. sasha C++ 2 03-11-2009 01:39 AM
Subtracting pointers: Which type to use to store the result? Spiro Trikaliotis C Programming 31 02-24-2006 07:11 AM
to store or not to store an image =?Utf-8?B?UnVkeQ==?= ASP .Net 6 03-30-2005 05:51 AM
arrays that store pointers user@domain.invalid C++ 1 08-06-2004 07:24 PM



Advertisments