Accessing Member Functions of Objects in Vector Stored on Heap

Hi..I've been searching on the forum for a good little while and have not found anything that explicitly covers my question; I'm sorry if I over looked. My question is this.

I have a class, simply called item and when I generate an instance of this I store this inside of a vector. I create an iterator that is pointed to the beginning of the vector and then use a pointer to return the current object that the iterator is pointing to. The vector is a vector of pointers of type item:

The class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class item
{
  protected:
    string name;
    int str, wis, con, intel;

    public:
       int getStr(){return str;}
       int getWis(){return wis;}
       int getCon(){return con;}
       int getInt(){return intel;}
       string getName(){return name;}
       void setStr(int a){str = a;}
       void setWis(int a){wis = a;}
       void setCon(int a){con = a;}
       void setInt(int a){intel = a;}
       void setName(string a){name = a;}

       item (string NAME, int STR, int WIS, int CON, int INT)
       {
           name = NAME;
           str = STR;
           wis = WIS;
           con = CON;
           intel = INT;

       }

       virtual void IamType () {
            cout << "I am a: " << name << endl;
            cout << "Str: " << str << endl;
            cout << "Wis: " << wis << endl;
            cout << "Con: " << con << endl;
            cout << "Int: " << intel << endl;

       }

};



ex of the vector of pointers function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
//Create object
item a("health potion",1, 2, 3, 4);
 
//Create vector and iterator
 vector<item*> Items;

//push item a onto vector
 Items.push_back(&a);
 
//point to first element of vector
vector<item*>::iterator iter;
 iter = Items.begin();

//assign pointer b to iterator
 b = *iter;

// print results
 b->IamType();



This code works correct and does what it is supposed to do (though I question if this is the best way to access the objects in each element. My problem occurs when trying a variation of this where I am placing the vector on the heap instead of the stack. When I do this I get a conversion error when trying to return the address of the iterator to a pointer to access the objects at each individual element.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//create object
item a("health potion",1,2,3,4);


//create vector on the heap returns pointer Items.    
vector<item>* Items = new vector<item>();
vector<item>::iterator iter;

//push item a onto vector
Items->push_back(a);

//set iterator to beginning of vector
iter = Items->begin();

//create pointer to iterator..breaks here giving a conversion type error

item* pItem = *iter;

//However the IDE shows that my pointer can see the member object that the iterator is pointed to.
pItem->IamType();

//If code executed...well self explanatory
delete Items;


If anyone is willing to assist in helping me understand why that won't work I would greatly appreciate their time :)
Last edited on
> where I am placing the vector on the heap instead of the stack
> vector<item>* Items = new vector<item>();
¿why are you doing that?

> When I do this I get a conversion error
Don't paraphrase.
The vector holds items, not pointers. When you dereference the iterator, you've got an item.

> However the IDE shows that my pointer can see the member object that the iterator is pointed to.
No, your IDE sees that you are trying to dereference a pointer, it does not known if it points to a proper location.

> where I am placing the vector on the heap instead of the stack
> vector<item>* Items = new vector<item>();
¿why are you doing that?



Two reason: 1) Personal edification, primarily in making something work and seeing if its possible. 2) because this may be useful if I want to encapsulate a large number of objects that I don't want disappearing when that function goes out of scope. I might not be understanding the proper application of vectors in a program. Are you implying that the first example, which I know works and does what I want it to do, is a better application of a vector?


> When I do this I get a conversion error
Don't paraphrase.
The vector holds items, not pointers. When you dereference the iterator, you've got an item.


I am not sure what you mean by not paraphrasing? Are you asking for the exact error message the compiler is returning? Furthermore, if the iterator is pointing to the item when I do iter.whateverfuction, why am I not seeing the member functions of the object? It is giving me the vectors functions I need to be able to see the objects member functions that are stored in that element. Once again I can do this with a vector of pointers, is this doable with a vector stored on the heap as well or am I misapplying the vector itself?


> However the IDE shows that my pointer can see the member object that the iterator is pointed to.
No, your IDE sees that you are trying to dereference a pointer, it does not known if it points to a proper location.


Yes I am aware of this; however, it is usually a pretty good guideline to show that I have things coded properly before compile time. It can obviously see what I am trying to do despite the compiler not liking the code.

I am simply writing this stuff for my own knowledge, and there is no real practical application (at least for now), so understanding why one works, the other doesn't, and if that second one can be done is what I am after. Can that second example work? If so, what am I missing?

Thank you.
Last edited on
kaneada wrote:
2) because this may be useful if I want to encapsulate a large number of objects that I don't want disappearing when that function goes out of scope.
You're circumventing the whole point of a scope, not to mention that your goal leads to poor program design.


You're circumventing the whole point of a scope, not to mention that your goal leads to poor program design.



Yes that was the point. To use a larger container for objects that I don't want deleted when the function goes out of scope. Which leads me back to my original question, which is can that second example work, if so how, and if not why not? Why make the heap available if not for breaking the scope of an application?
The heap is available for dynamically allocating objects at runtime based on runtime circumstances that cannot be known at compile time.

Why wouldn't you want the container deleted when the function goes out of scope? You could return the container from the function, you shouldn't give a pointer and expect someone somewhere at some point in time to delete it themselves and hope no one is still using it.
At one point I thought it was a good idea to push pointers to objects onto a vector. My reasoning was than it was more efficient that copying the object.

I have long since become convinced that's a false economy. The real issue becomes one of who "owns" the object pointed to. Does the vector own it? If so, then you have a memory leak. The vector's desctructor won't clean up the pointed objects. Of course you could write a class that inherits from the vector that has a customer destructor that does the cleanup, but that's just more complication. If something other than the vector "owns" the pointed objects, when does it release the pointed objects? Then what happens to the references in the vector? If you're going to do this, then you really need to use unique_ptr (or auto_ptr).

Pushing the object itself makes much more sense. The objects in the vector are automatically destructed when the vector goes out of scope. Simple. No complications. The cost of copying an object is minimal.


Does the vector own it? If so, then

If so, then the correct container is boost::ptr_vector<T> or std::vector<std::unique_ptr<T>> (but never auto_ptr!). Although it is true that common use case for vectors is vectors of objects themselves, not pointers to them, when runtime polymorphism is required, a vector holding (and owning) pointers to bases may be necessary.

That's not directly related to vector<item>* Items = new vector<item>();, which has no reasonable justification at all.
Last edited on
Thanks guys...those three explanations put things in perspective!
Topic archived. No new replies allowed.