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
Related
I'm getting to grips with references in C++ and I have a small query surrounding references & scoping, for this it's probably best to create an example:
Imagine I have a method in "BankDatabase.cpp" which takes a bank record by reference and adds it to a data structure (also by reference).
void AddRecord( BankRecord& bankRecord )
{
//Add record to data structure by reference
}
If I run a method like so:
void TestAddRecord( BankDatabase& bankDatabase )
{
BankRecord bankRecord { "John", "Doe", 9999 }
bankDatabase.AddRecord( bankRecord );
}
To my mind, "bankRecord" falls out of scope (as do its two strings and int) and is thus cleared from memory at the end of the "TestAddRecord" method, leaving "bankDatabase" pointing at some empty memory?
If so what's the general accepted standard / resolution to such a scenario? It seems a little mad to have to pass things by value...
In that case passing by value seems like the way to go. Allocating a new BankRecord pointer will work too. Storing things by reference is not very great.
However if I'm not mistaking, your two strings and the int won't be lost since they are present in the stack and will not be deallocated. But bankRecord will still be lost.
The best way to answer these concerns is to step through the code in the debugger and see what the Vector is doing with the variable being appended. Look especially at the constructor calls as you step into the data structure's Append functions. Because I do not know your underlying data structure, it is a bit more difficult for me to tell you more information. I will assume it is a std::vector for now until told otherwise.
You may be surprised to learn that references passed through a function do not tell the entire story about when it will go in and out of scope. I often think of C++ references as pointers that do not need nullptr checks.
Your code will work fine as long as the reference is copied into the vector or does not go out of scope because the variable it pointed to was destroyed. The reference will not go out of scope if it is referring to a member variable or memory on the heap for your particular case.
If the reference was declared on the stack to a variable created on the stack, and then appended to the vector, then you will have scope problems.
You should also look into emplace() if you have C++11 and the compiler supports move semantics.
In short, the most important thing you can do here is step through the code and see what Constructors are being called. This will give you the answer you desire.
First time I'm posting to stack so if I'm not following the correct procedure, instruct me to do better and I will.
Ok, I have quite a big project with lots of classes and I cannot share code at this point, but if necessary I will write a dummy file to further explain. Hopefully I will be clear enough without that.
I have this class method that receives as params a vector: std::vector< myClass > &objects_1.
Some of these will be bound (logically) to other objects in the class. The important thing to keep in mind is that I have to modify some of the received objects_1 without using the vector indexing (as it may change along the way)
Also unfortunately it is relevant for the function to have this exact signature.
The way I do it now is by having several pointers initialized with nullptr that, sooner or later point to elements of the objects_1 vector.
My questions are: is this a bad practice? Do I have to delete the pointer or does the destructor takes care of this? Is there a better way to do this? I tried std::shared_ptr but as someone pointed out these are intended more for allocating memory dynamically.
I have a question about using multiple pointers to an object.
I have a pointer in a vector and another one in a map.
The map uses the vector to index the object. Example code:
class Thing
{
public:
int x = 1;
};
Thing obj_Thing;
std::vector<Thing*> v_Things;
v_Things.push_back(&obj_Thing);
std::map<int, Thing*> m_ThingMap;
m_ThingsMap[v_Things[0]->x] = v_Things[0]; // crucial part
is it good practice to assign pointers to each other like this?
Should the vector and/or map hold addresses instead? Or should I be using a pointer to pointer for the map?
It all depends on what you want to do.
However, your approach can get really hairy when your project grows, and especially when others contribute to it.
To start with, this:
m_ThingsMap[v_Things[0]->x] = v_Things(0);
should be:
m_ThingsMap[v_Things[0]->x] = v_Things[0];
Moreover, storing raw pointers in a std::vector is possible, but needs special care, since you may end up with dangling pointers, if the object that a pointer points to gets deallocated too soon.
For that I suggest you to use std::weak_ptr, like this:
std::vector<std::weak_ptr<Thing>> v_Things;
in case you decide to stick with that approach (I mean if the pointer points to an object that is pointer-shared from another pointer).
If I were you, I would redesign my approach, since your code is not clean enough, let alone your logic; it takes one moment or two for someone to understand what is going on with all the pointers and shared places.
Hey first question I'm asking here many thanks in advance.
I'm using a vector to store a series of pointers to objects of a class CSquare, I want to have an iterator that I can pass around so that I can access the functions of a certain object. This is my current code to attempt this with no luck. IntteliSense telling me that there are 'No members Available'.
vector <CSquare*> pSquares;
//filled in vector
vector<CSquare*>::iterator tempIt = pSquares.begin();
tempIt->getName();
Not sure what else to add, but if you need anything else to help me out please say.
Again thanks a lot.
Edit: Problem solved, I had to dereference twice. The following code works, thought I'd just leave this up incase anyone else need the same help, thanks for looking anyway.
vector <CSquare*> pSquares;
//filled in vector
vector<CSquare*>::iterator tempIt = pSquares.begin();
(**tempIt).getName();
Remember that you need to dereference the iterator to get the pointed-to thing. Because this is a vector<CSquare*>, your iterator is effectively a pointer-to-pointer-to-CSquare, so you need to do this:
(*tempIt)->getName();
You need an extra dereference:
(*tempIt)->getName();
The reason is that what you are storing inside the vector are pointers, so *tempIt is a reference to a pointer that you need to dereference again to access the CSquare object.
I've got a function that takes a list of CRuntimeClass pointers in order to setup a view. I'd like to return without doing anything if the function is called with a list of the same classes that are already setup. Saving the pointer values and comparing them on the next call is currently working, but I want to verify that that's a legal thing to do, and not something that just happens to work. Maybe my doc-search-fu is lacking, but I can't find anywhere that guarantees the pointer value returned from the RUNTIME_CLASS() macro for a given class will be the same for the life of the program. The closest I could find is in the docs for CObject::GetRuntimeClass():
There is one CRuntimeClass structure for each CObject-derived class.
That implies that the pointer value shouldn't change, but doesn't exactly state it. Does anyone have something a bit more concrete on that? Or is there a better way to compare the CRuntimeClasses?
No such guarantee is documented, albeit that it is likely. You are supposed to use CObject::IsKindOf().
Taking a peek at afx.h plus a little of debugging shows that RUNTIME_CLASS() returns a pointer to a static member: static CRuntimeClass class##class_name (as it can be seen in the definition of DECLARE_DYNAMIC(class_name) macro).
As the member is static, the pointer to it does not change during runtime. In other words static is your guarantee.