[...] suggests even for graphs to not do something like this.
Data Structure POV
This is just going to be a variety answer from the data structure standpoint rather than a comprehensive one, but I've created some data structures for which I couldn't find any way to avoid the raw pointer back from child to parent. That might have just been a defect in the way I was approaching it. As a caveat, I'm assuming "pointer" here means "raw pointer" which implies to me that the child is simply "referencing" the parent but not owning it (circular ownership would be a huge problem, especially in C++ if you used like a
shared_ptr in A to B which stores a
shared_ptr back to A -- this would end up just leaking memory since there's no protection against cycles like this there).
I ended up using such a data structure as the heart of this program: https://www.lightwave3d.com/chronosculpt/ -- a little teeny software I wrote (not my proudest moment as I had to code the whole thing with the exception of interchange support and licensing on my own, and in a matter of months -- also my last work at a company setting since I got fed up with that kind of environment).
The problem is that I needed to deal with meshes which were animating and being sculpted interactively with millions of polygons (sometimes with every single vertex moving at every single frame) at acceptable frame rates, while also providing reasonably-fast spatial searches for things like picking, sculpting, and collision.
Normal spatial indexing structures like bounding volume hierarchies are often what we use, and I tried to use a variety of these including a loose-fitting one with expanding bounding boxes. Yet it was too difficult to meet those 30+ FPS demands on like an i3 when I had a 7 million triangle mesh of a creature running to update this data structure every single frame with all these vertices moving around.
These data structures tend to be ideal for static content that's not deforming every frame, or at least not dynamic content of this sort that spans in the millions of vertices. Intel's BVH was considered to be really great for being able to handle deformations of meshes with 30k polygons at over 30 frames per second in a raytracer context, but I was looking at a need for millions of polygons at such a frame rate in an OGL context (not as critical for searching as a raytracer, but needed dramatically faster updates of the acceleration structure in response to deformation).
So the data structure I designed was not based on spatial partitioning. I probably can't give too away too many details for IP reasons, but the key to rapid updates was based on the stability of the hierarchical structure. It didn't need to split nodes apart or rebalance the tree or anything like that. All it needed was to update bounding boxes bottom-up, starting from a list of modified vertices and working upwards and updating bounding boxes to the root.
That was the key to getting the necessary frame rates, and the bottom-up access pattern made it so I couldn't really see a way to avoid the back pointer. I tried initially to avoid it and mark all the leaf nodes as "dirty" first, then traverse the tree from top-down looking for dirty leaf nodes, but I couldn't get the desired performance that way working top-down instead of bottom-up for localized edits to mesh (sculpting, e.g.). It ended up being cheaper to just store some state with these nodes (they were "fatter nodes" for an n-ary tree) so that fewer nodes would need to be accessed working bottom-up from the vertices that were moved and propagating updates up the tree.
Maybe I did something wrong. I just couldn't find a way around it. It was in a rush setting so maybe I just didn't take the time to properly think through and come up with a new data structure that avoids the problem. I've been thinking about this for a while since this question was raised though and I still can't come up with a way to avoid the back pointer, so maybe that's one legit case to do this (unless I have a huge blind spot, which is very possible).
Simplified diagram of the idea (though actual one was n-ary):
Wasteful Back Pointers
I've seen some data structures published where back pointers were used by the authors just for convenience, like with a tree that is always traversed top-down but then works its way back up from leaf to root. The developers were too lazy to construct a stack or recursively pass a parameter, so they just used a back pointer as a kind of convenience. There I can see how it can be really bad, especially when publishing a paper on such an algorithm and then using the back pointer when it could easily be avoided.
In those cases the back pointer seems wasteful, and possibly even more error-prone (more persistent, avoidable state can make things harder to manage).
I'm hoping my example doesn't fit in that category, since I think mine really absolutely needs the bottom-up traversal. In my case, the list of leaf nodes to affect wasn't always obtained starting with a top-down tree traversal. It was sometimes obtained through other data structures, like the mesh data structure traversal itself. This was the main reason I felt I couldn't avoid the back pointer even though they're usually quite wasteful.