I work on graphics applications and have been using shared & unique pointers essentially because it handles memory deallocation for me (aka as a convenience) which is probably bad (if that's the reason why I use them).
I read the answer to a question on Stackoverflow recently that mentioned that according to B. Stroustrup, unique/shared ptrs should generally not be used and that arguments should be passed by value instead.
I have a case in graphics for which I think using shared_ptr makes sense but I'd like to know from experts (I am not C++ experts) if I am over doing/thinking it and if so what they would be doing instead (to conform to C++ recommendations and for efficiency)
I will take a general problem that occurs in Rendering/Ray-Tracing. In this particular problem we have a pool of objects (we will use triangles for this explanation) and a structure which for the simplicity of the explanation we will refer to as regular 3D grid. Let's say that at some point we need to insert the triangles into the grid: what that means is that we need to check of the bounding volume of each inserted triangle overlaps any of the cells from the grid, and it does, then each overlapped cell needs to keep a pointer/reference to that triangle (for later use). A triangle may overlap more than 1 cell, so it can be referenced multiples times by several cells (you see where I am going with the shared_ptr here).
Note that outside of the grid structure, we don't need the pool of triangles (so technically the object that owns the pool of triangle here, is the grid or more precisely the grid's cells).
class Grid
{
struct Cell
{
std::vector> triList;
};
void insert(triangle*& tri_)
{
std::shared_ptr tri = tri_;
for (each cell overlapped by tri) {
// compute cell index
uint32_t i = ...
cells[i].triList.push_back(tri);
}
}
Cell cells[RES * RES * RES];
};
void createPoolOfTrianglesAndInsertIntoGrid()
{
Grid grid;
uint32_t maxTris = 32;
Triangle* tris = new Triangles[maxTris];
// process the triangles
...
// now insert into grid
for (uint32_t i = 0; i < maxTris; ++i) {
// use placement new
Triangle* tri = new (&tris[i]) Triangle;
grid.insert(tri);
}
// no need to delete tris here ... it should be done by
// the grid when we go out of this function's scope
}
It sounds complicated but my motivation behind this design is to follow Stroustrup's recommendation. In this case the function createPoolOfTrianglesAndInsertIntoGrid doesn't owned the triangles, it's the cells of the grid that do. So I allocate the memory in the function createPoolOfTrianglesAndInsertIntoGrid because this is where I need to create the triangles, and I then use the placement new method to get a pointer to each triangle in that pool which I can then pass to the grid insert method (I defer memory management of that object to that method). In there, it converts the triangle into a shared_ptr and cells can now share a "reference" to it (using shared_ptr).
I wanted to know if to your opinion this was going in the right direction, or if this appears completely wrong, both in terms of implementation and in terms of possible loss of efficiency (I allocate a pool of memory, then use the new placement to create a temp triangle, which I then pass on to the grid insert method, then convert to shared_ptr, ...)
I am trying to both learn, and improve my code and hope you can provide valuable professional feedback.
EDIT: basically I am trying to find the right approach to that problem + I will try to provide later some modifications based on your comments
JavaScript questions and answers, JavaScript questions pdf, JavaScript question bank, JavaScript questions and answers pdf, mcq on JavaScript pdf, JavaScript questions and solutions, JavaScript mcq Test , Interview JavaScript questions, JavaScript Questions for Interview, JavaScript MCQ (Multiple Choice Questions)