I have the following trimmed class: #include <vector> #include \"Tile.h\" class
ID: 659156 • Letter: I
Question
I have the following trimmed class:
#include <vector>
#include "Tile.h"
class Board {
std::vector<Tile> boardArr;
// VVV Bad Practice? Safe?
Tile& getTileAt(unsigned int x, unsigned int y);
public:
Board(int width, int height);
};
Note that the vector remains the same size once the class is initialized; I have no methods to modify it. From what I understand, vectors are guaranteed to not move around, unless it's required to resize, so a reference into it should be safe in this case.
From what I can tell, this should be safe. The method is private, so there shouldn't be any way for references to leak.
The best alternative to the above function is to return a copy of the Tile, modify it, then copy the modified tile back. I found using it directly a lot cleaner, so I'd prefer it if it's safe.
This will be single-threaded, and so far, it's only use is to do simple things to a tile, like toggle an internal flag. An example of how I'm using it:
TurnResult Board::flipTile(unsigned int x, unsigned int y) {
return getTileAt(x, y).flipTile();
}
void Board::setTileFlag(unsigned int x, unsigned int y, bool flagState) {
getTileAt(x, y).setFlag(flagState);
}
Explanation / Answer
No, it is not bad practice. However, you need to make sure you manage memory correctly. By having raw objects in the vector and returning a reference, you may have a reference be null which is not allowed. This will break your program at some point if you manage to have a dangling reference.
Here is another way using shared pointers:
#include <memory>
#include <vector>
class Board {
std::vector<std::shared_ptr<Tile>> boardArr;
// VVV Bad Practice? Safe?
std::shared_ptr<Tile> getTileAt(unsigned int x, unsigned int y);
...
};
TurnResult Board::flipTile(unsigned int x, unsigned int y) {
return getTileAt(x, y)->flipTile();
}
void Board::setTileFlag(unsigned int x, unsigned int y, bool flagState) {
getTileAt(x, y)->setFlag(flagState);
}
Shared pointers ensure that the target object still exists because they use reference counting to see if any other pointers point to the same object. Unique and shared pointers are safe to use with STL containers (the old smart pointers are very unsafe due to lack of move semantics).