How to Create & Store objects into a Vector dynamically

Pages: 12
"AFTER SOLVED" EDIT:
This technique gives the ability to dynamicaly create an object each time and send it to a vector.
By this way you wont any more have to pre-create an Array of 100 objects and keep an i pointing the last of the objects used until now, neither transfer it from func to func along the Object Array it self

---------------------------------------------------------------------------------------------------------------------------------------

This is NOWHERE on the WEB until my search sizei.

I want to new a object and put it to a vector

1
2
3
vector <CLIENT *> vCLIENT;
vCLIENT.push_back(new CLIENT(1,100)); //CLIENT(int ID, int credit){...}//constr
vCLIENT.push_back(new CLIENT(2,100));


All ok BUT WHEN I

 
cout<<vCLIENT[0].getID(); //class CLIENT::int getID(){return ID;} 


Says "...which is of non class type 'CLIENT*'"

if i put
 
cout<<*vCLIENT.getID(); //class CLIENT::int getID(){return ID;} 


Says "...has no member named 'getID' "

Seems logicless
Please help couldnt find it anywhere in tens of of forum and hours search.

--------------------------------------------------------------------------------------------------------------------------------------
SOLUTION ("AFTER SOLVED" EDIT)

The . has higher precedence than *, so what you need is (*vCLIENT[0]).getID(). To make it less of a mess, there is ->. Then it is vCLIENT[0]->getID(). (by hamsterman )

1
2
3
4
5
6
7
8
9
vector <CLIENT *> vCLIENT;
    
 vCLIENT.push_back(new CLIENT(0,100)); //CLIENT(int ID, int credit){...}//Class's construcor
 vCLIENT.push_back(new CLIENT(1,150));
    
 cout<<"\nID:"    <<vCLIENT[0]->getID(); //class CLIENT::int getID(){return ID;}
 cout<<"\nCredit:"<<vCLIENT[0]->getCredit();
 cout<<"\nID:"    <<vCLIENT[1]->getID();
 cout<<"\nCredit:"<<vCLIENT[1]->getCredit();


The use of pointers can also be avoided along with -> and use . instead. A debate on the need or not of pointers has taken place
Pointers may be used when:
_ You don't have the ownership of the objects, but you are referencing them.
_ You want to use polymorphism
_ The class doesn't have a copy constructor (maybe the new standard have something to say about this)
(by ne555 & moorecm)
Last edited on
. has higher precedence than *, so you're doing *(vCLIENT[0].getID()), assuming you missed that [0] by mistake, while what you need is (*vCLIENT[0]).getID(). To make it less of a mess, there is ->. Then it is vCLIENT[0]->getID().
Last edited on
I think the vector class automatically does the dynamic allocation so you don't have to do it yourself.

This could work too.
1
2
3
4
5
vector<CLIENT> vCLIENT;
vCLIENT.push_back(CLIENT(1,100));
vCLIENT.push_back(CLIENT(2,100));

cout << vCLIENT[0].getID();



EDIT: I just tried hamsterman's suggestion and that worked too although I'm not sure how to delete the new objects.
Last edited on
closed account (zb0S216C)
Don't use the std::vector with new/delete.

Wazzak
[ WOOOW IT WORKS! OH THANK YOU VERY MUCH I HAVE ALL THE MORNING!! ]

SO the Solution is:

1
2
3
4
5
6
7
8
9
10
 vector <CLIENT *> vCLIENT;
    
 vCLIENT.push_back(new CLIENT(0,100)); //CLIENT(int ID, int credit){...}//Class's construcor
 vCLIENT.push_back(new CLIENT(1,150));
    
 cout<<"\nID:"    <<vCLIENT[0]->getID(); //class CLIENT::int getID(){return ID;}
 cout<<"\nCredit:"<<vCLIENT[0]->getCredit();
 cout<<"\nID:"    <<vCLIENT[1]->getID();
 cout<<"\nCredit:"<<vCLIENT[1]->getCredit();


P.S.
---------------------------------------------------------------------------------------------------------------------
Hamterman or someone other please for the problem's total and consistence covery, you may post a mini-article on the Theoritical background of the issue why -> and not . simple, it has something to do woth pointer leveling i think.
Someone suggested use of itterators but was useless dont know if has anything to do
Last edited on
ATTENTION TO ADMINS: THIS IS NOWHERE FOUND ON THE INTERNET by the most common google search terms that one can imagines.

IF NOTHING IS TO BE ADD, CLOSE THIS THREAD AND ARCHIVED IT IMEDIATELY. ALSO USE IT TO UPDATE YOUR VECTOR ARTICLE. Its the most vital example that should be found on any vector article yet there is nowhere.

I may not click solved yet for 1-2 days that may other interesting optionals, and theoritical or further pratical coverage of the existing one are to be added by others. Please be welcome in the mean time
Last edited on
How would one delete a vector object?

Framework, what is your reasoning behind your statement? I'm actually interested.
closed account (zb0S216C)
Have you considered exceptions, Stewbond? If the std::vector throws an exception during its reallocation/deallocation, and the caller doesn't handle it, the program terminates; thus, the elements of the vector won't be freed.

It's just one of those situations that don't often happen, but handy to know about.

Wazzak
Last edited on
So whats the wright method if I want to dynamicaly create objects and store them to a vector?
closed account (zb0S216C)
Use std::auto_ptr, or make your own automatic pointer.

Wazzak
Where can I find an example code?
closed account (zb0S216C)
This website has reference documentation on auto_ptr[1].

References:
[1] http://www.cplusplus.com/reference/std/memory/auto_ptr/


Wazzak
Last edited on
@Framework, don't generalise. There are situations when having a vector of pointers is needed. Although he probably is just wasting time and space. As for exceptions, if they're not handled, you're going to crash with or without pointers. Luckily, in your post, that 'often' is really 'ever'.

@imakaia, instead of a vector of pointers to CLIENT, have a vector of CLIENT. Then remove 'new', replace '->' with '.' and remove 'delete's if you have any. This really isn't any kind of undocumented case. Just natural use of arrays (mimicked by vectors) and pointers.
closed account (zb0S216C)
Hamsterman, If you use new when pushing back a std::vector, it's best to have a class of some-kind to handle deallocation in the event of a crash, and even free you from the burden of deleteing every element. Besides, exceptions do happen, it's just a matter of handling that situation if it ever arises.

Wazzak
So like stewman sed if i just remove thepointer ( * ) it will be the same and work?

1
2
3
4
5
6
7
8
9
 vector <CLIENT > vCLIENT;
    
 vCLIENT.push_back(new CLIENT(0,100)); //CLIENT(int ID, int credit){...}//Class's construcor
 vCLIENT.push_back(new CLIENT(1,150));
    
 cout<<"\nID:"    <<vCLIENT[0].getID(); //class CLIENT::int getID(){return ID;}
 cout<<"\nCredit:"<<vCLIENT[0].getCredit();
 cout<<"\nID:"    <<vCLIENT[1].getID();
 cout<<"\nCredit:"<<vCLIENT[1].getCredit();


Its just i wont be able to delete the objects?
Last edited on
closed account (zb0S216C)
You will be able to, you'll just have to delete each object manually. But if you used std::auto_ptrs, you won't have to do any deallocation since it does it for you.

Wazzak
Er... To remove an object from a vector im just deleting it normaly with vector function erase eh?

Or the object memory itself wont be deleted and i have also to put a delete to some special position?
Last edited on
Framework, please stop posting false information.

First std::auto_ptr is deprecated in C++11. Second, it should NEVER be stored in a vector because of it's transfer of ownership semantics on copy. Third, after an exception terminates the application, the memory will be reclaimed by the OS anyway.

I agree that a smart pointer is the best approach here, such as a shared_ptr.

In the simplest case, the objects can be deleted by iterating through them like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vector <CLIENT *> vCLIENT;
    
vCLIENT.push_back(new CLIENT(0,100)); //CLIENT(int ID, int credit){...}//Class's construcor
vCLIENT.push_back(new CLIENT(1,150));
    
cout<<"\nID:"    <<vCLIENT[0]->getID(); //class CLIENT::int getID(){return ID;}
cout<<"\nCredit:"<<vCLIENT[0]->getCredit();
cout<<"\nID:"    <<vCLIENT[1]->getID();
cout<<"\nCredit:"<<vCLIENT[1]->getCredit();

//...

for( vector< CLIENT * >::const_iterator i = vCLIENT.begin(); i != vCLIENT.end(); ++i ) {
    delete *i;
}
vCLIENT.clear();

Last edited on
Hmm smart and practical :D ;)

So I would have had problems without pointer type (*) though it would run.
Thank you very much
Assuming CLIENT has a copy constructor you can do it without pointers like this:
1
2
3
4
5
6
7
8
9
vector <CLIENT> vCLIENT;
    
 vCLIENT.push_back(CLIENT(0,100)); //CLIENT(int ID, int credit){...}//Class's construcor
 vCLIENT.push_back(CLIENT(1,150));
    
 cout<<"\nID:"    <<vCLIENT[0].getID(); //class CLIENT::int getID(){return ID;}
 cout<<"\nCredit:"<<vCLIENT[0].getCredit();
 cout<<"\nID:"    <<vCLIENT[1].getID();
 cout<<"\nCredit:"<<vCLIENT[1].getCredit();

That way all your CLIENT objects will be destroyed automatically when the vector goes out of scope.
Pages: 12