sometimes when a class has attributes that are pointers, it can be confusing whether this object is responsible for deleting the object being pointed to.
I would like to know if it is a common strategy to have class attributes that are references. With references this confusion would not be there.
So I thought I can say: "if an object A is the owner of another object B and is responsible for deleting it, then it will have as an attribute a pointer to it. If an object A uses another object B but is not responisble for creating or deleting it, then it will have a reference to it".
for example
1 2 3 4 5 6 7 8 9
class A
{
B* b; // A is responsible for creating and destroying b
}
class C
{
B& b; // C is merely using b and is not responsible for creating and destroying it
}
Does anybody know if that is common? Or are there drawbacks that I am not aware of?
References do not keep objects alive, so the object that C::b references could be destroyed before the instance of C, and it would be a dangling reference. It is common to have references as data members, but it depends on the use and situation. It also affects the size of your data structure depending on your compiler's implementation of references - usually it is a pointer, but there's no guarantee (it usually doesn't matter anyway).
To determine if you should use references or not, as with anything, consider how it is to be used and dealt with. ;)
I would argue that by holding a raw (C-style, "dumb") pointer, you're saying that A is not responsible for creating or destroying B. Consider struct node {node* prev; node* next;} for example.
The issue with non-static reference members is that they render your classes non-assignable (assignment replaces the contents of a class, but a reference cannot be reseated), which isn't always desirable. You could write your own assignment that doesn't touch the reference members, but the semantics become unclear (so the objects aren't equal after assignment? If equality skips the reference too, why isn't it just static?) I use non-static reference members, but not too often.
@Cubbi afaik it is ok to do something like this->~MyClass(); new (this) MyClass(TheNewReference); in the assignment operator, despite it being extremely disgusting. It's worked with my compiler in tests, though I've never used it in actual code.
std::reference_wrapper<T> internally stores a pointer to T.
Though it exposes (copy constructible and copy assignable) reference semantics instead of pointer semantics.
thanks! I did not know that a reference cannot be reassigned. That is a major argument for not using them as class memebers in most cases, i guess! The reference_wrapper seems an interesting alternative.