Updating vector of class objects using push_back in various functions - c++

I have a vector of class objects I've created in main by reading in a data file. I'm then passing around the vector to several different files containing functions that perform different operations on the vector (sorting by different fields, subtracting inventory, etc.). I'm running into a problem when I try to use push_back to add to the vector in another file (that's a part of the same project) after it's already been created. The pre-existing vector is passed to the function and the vector is successfully added to within the function, but when I exit the function the added record is no longer there, and, as far as I can tell, I should be accessing the updated vector after that point forward from all my different functions in different files, right? I shouldn't have to pass the updated vector back if it's the same name as the one I created in main, should I? I'm sure the language and terminology I'm using are wrong (and please feel free to correct me), but it's almost as if the vector isn't updating globally and is only updating locally within the function for the duration of its call.
This is the function definition and code within the function I'm using where I want to add to the vector (I'm skipping all the variable parameter assignments for the sake of brevity). All of the functions I'm pointing to are the setter functions within the class, and prior to this point the vector already contains 20 records, and was set up similarly to the below function.
void addBook(vector<BookData> books)
{
BookData *books1;
books1 = new BookData;
books1->setTitle(bookTitle);
books1->setAuthor(author);
books1->setPub(publisher);
books1->setIsbn(isbn);
books1->setWholesale(wholesale);
books1->setRetail(retail);
books1->setQty(qtyOnHand);
books1->setDateAdded(dateAdded);
books.push_back(*books1);
}
I didn't want to flood the post with too much code but I can post more if it'd be helpful. I just want the additions (or deletions I make in another function) to be accessible throughout the whole program.

You should pass the vector by reference to modify the original global vector.
void addBook(vector<BookData>& books)
^^^
Otherwise you are passing a copy of the original vector to the function and modifying that not the global version.

You need to pass your vector as a reference wherever necessary. In that specific instance, you just need to change
void addBook(vector<BookData> books)
to:
void addBook(vector<BookData>& books)
otherwise your function gets a copy of the vector, not a reference to the original one.

Related

Should i use pointers or references?

I'm having problems figuring out if i should use pointers or references in certain methods
I have a method called issueOrders(Orders* order) which takes a reference to an Orders object
This method should add the pointer to order to a vector containing pointers to orders
void Player::issueOrder(Orders* order)
{
ordersList->getOrdersList().push_back(order);
}
where ordersList is an object containing a vector of ordersList as parameter
Like this:
class OrdersList{
private :
vector<Orders*> ordersList
public:
vector<Orders*> getOrdersList();
}
But the issueOrders method doesnt work, that is, nothing is pushed in the vector and im confused as to why.
Thanks for reading and any help is appreciated! :)
As #UnholySheep pointed out, your getter returns a copy of the ordersList vector. What you want is a reference (or a pointer), so that your push_backs affect the vector. So you want to change its declaration to this:
vector<Orders*>& getOrdersList();
And change its definition accordingly.
Whether or not you should store your Orders as pointers or references has nothing to do with the problem. And as the correct answer to the question in your title is largely dependent on the type of the data and the way it's going to be used, it's hard to give you an answer with just the code snippets. I suggest you take a look at this answer: https://stackoverflow.com/a/8259173/13191576

c++ passing objects to functions

I am working on a project dealing with many different operations with sets. I have a specific question about passing by reference. In the header file I have created an object called SoS which stands for set of strings and its private data members are a vector of strings called m_vos and a boolean called m_cofinite. Here is an example of my confusion with the intersection function I am creating.
SoS::makeIntersection(const SoS& B) const {
}
This is the function I am creating and It needs to create an intersection of the sets. I would approach this by looping through and putting both sets together and then removing elements that arent a part of both original sets therefore giving me the intersection of the two. I know logically how i could do this but I am confused as to what I am passing into the function and how I am able to use two sets when only one appears to be passed in(I was told I can not change the structure of the function so it needs to be this way). Any help is greatly appreciated.
The first set is this and you access its members like this->m_vos.... The second set is the one you passed in and you access its members like B.m_vos....
However, for brevity, you can omit the this-> unless there is a name conflict between a local variable and a member variable. So you can do simply m_vos... and B.m_vos....
Also you need to consider what your function will return? Maybe the intersection you create? That would be a third SoS variable that you might return as a result:
// return type SoS
SoS SoS::makeIntersection(const SoS& B) const {
SoS intersection; // this is the new SoS that will be the intersection
// fill intersection.m_vos using B.m_vos and this->m_vos
return intersection; // return the intersection version
}
The object on which you called the function can be accessed through this. The second object is the argument to the function.
The first vector of strings is this->m_vos.
The second vector of strings is B.m_vos.
Your statement:
I was told I can not change the structure of the function so it needs to be this way
does not make sense to me.
The function does not seem to have a return value. Did you forget to include it in the posted code? How will the resultant object, the intersection, be returned to the calling function?
You cant' modify this to be the resultant object since the function is a const member function.
You cant' modify B to be the resultant object since it is passed by const&.
The way to call member functions for a class is through its objects(if not static). To get the intersection of two sets(sos objects) you'll call the function using one of the SoS object and pass the other one as the parameter reference.
Inside the member function the object which you've used to call it can be derefenrence using this pointer. Read more here and here.

How would a QList containing pointers behave when passed by value

Suppose you have QList containing pointers QList<SomeThingCool*> and you pass it to a method with a signature void doCoolStuff(QList<SomeThingCool*> list) what would the space and time implications be of such a call?
My guess is that there will be some overhead because a copy will be created of the QList object, we however do not need to do a deep copy since we are dealing with pointers.
One difference in behaviour would be that if doCoolStuff makes modifications to the list, the original list will remain untouched.
What you are writing is correct for generic C++, however QList, among some other Qt classes, is a bit special when it comes to this. It is implicitly shared a class, aka. copy-on-write (COW). What does that mean, yeah?
The only addition to your explanation is that if you do not intend to modify the list inside the body of the method or function, your list be implicit shared, which means a shared data pointer will be only the extra space constraint.
If you intend to modify the list inside the function or method body, then there will be a deep copy made for the list. Naturally, your pointers will still remain shallowly copied because they are pointers.
As for the time dimension, by implicitly using this technique for this class, you spare the time spent on copying the list if you do not do any modification.

Making a list of variables without copying them

The Main question:
How do you create a pointer to a variable that can be stored and then used to access this variable at a later time Without a copy being created
The below is here just to answer any questions that people might have as to why I want to do this
Prologue:
I am making a game with DirectX and I want to create a "list" of Entities(A special class) in a another class. I want to do this so I can keep track of all the objects in the game that are rendered by a specific method(One list for triangles, another for lines, ect). To do this I originally just had a class and it had a std::vector<Entity>, the class then had an add(Entity entity) function which would add the specified entity to the vector. This worked out very well until I started trying to make changes to these entities in the vector.
The problem:
First I would create an entity in the main world loop, Entity testEntity = Entity(position); then I would add it to the entity list, entityList.add(testEntity);. When this command is called it is actually just making a copy of the entity as it is at the time that the add command was called. This means that there are suddenly 2 entities that represent 1, The entity in the main world that is being affected by all the game logic, and the entity in the entityList that does not update, but renders. These two are not in sync.
The desired effect:
The entityList's std::vector is actually just filled with some sort of pointer to the entities in the world loop. Then when an entity is updated in the world loop the entityList has the same data for that entity.
It's not entirely clear to me where you're having trouble, so this may not answer the question:
It seems like you want to just store a vector of pointers to Entity objects. I.e. std::vector<Entity*>.
If you know that testEntity will be in scope for the lifetime of the vector, you could just add a pointer to it to your vector. I.e. entityList.add(&testEntity).
If that assumption isn't true, you probably want to allocate your Entity objects on the heap (e.g. Entity* testEntityPtr = new Entity(position);. If you're using C++11 (or maybe even if you're not), you probably want to use shared_ptr and make_shared in this situation.
You could possibly use the c++ 11 Move Semantics to preserve your data. If Entity have pointer members that point to some allocated data that you do not want to copy you could implement Move semantics that would essentially transfer ownership the the copy that you are placing in the vector.
For example:
Entity(Entity&& entity)//move constructor
{
this->data = std::move(entity.data);
//and so on.
}
You will also need a "Move assignment operator" Entity& operator=(Entity&& entity);
You will need to look up "Move Semantics" and "rvalue references" for more info.
I hope this helps.

Is it safe to store a local declared object in a global QList?

I got a CPP program where i make a local object A and want to store it in global object B which is a QList.
Is it save to statically allocate object A or do i need to use the new keyword.
Does QList uses the copy constructor?
Thanks
QList stores copies of objects, so it should work. However make sure that copying is indeed what you want. If this isn't the case, allocate your object with new and store the pointer in the QList.
No. Inner scope variables should not be stored in outer scoped variables. You can store the values, but not the reference/pointer to that variable.
QList has only a pointer to it's contents. So whenever you make a copy of a QList it doesn't actually copy all of the contents, it just copies the pointer. Whenever you modify a list, a copy is made to ensure that it's not modifying the contents of other objects. See this: http://doc.qt.nokia.com/4.7-snapshot/qshareddatapointer.html
QList does use the copy contructor, so if your objects contain a lot of data, it might be not good to use straight objects in the QList, since copying can cause some overhead when the list needs to grow.
Another solution would be to use QSharedDataPointer to create functionality similar to that of the QList.
Note that most of Qt classes already use this, so if you class contains things listed here: http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html It's somewhat unnecessary to use the QSharedDataPointer.
There is one thing that you didn't make clear that has of relevance, I think. Do you want the global static object A to have the same data as the object on the list?
This is achieveable by using either pointers or QExplicitlySharedDataPointer.
QExplicitlySharedDataPointer is much the same as QSharedDataPointer, with one exception.
It doesn't make a copy of the data when it's modified. Here's some documentation http://doc.qt.nokia.com/4.7-snapshot/qexplicitlyshareddatapointer.html
I'v used those classes a lot and I'v found them very useful and not hard at all to use.
nope. QList stores the list of pointers to objects, so local variables should not be stored in the global QList.
check out this link for details:
http://twl.pl/jtz/Inne/QT-Tutorial/qlist.html#details