references as class attributes

Nov 27, 2012 at 4:27pm
dear all,

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?

Greetings
Nov 27, 2012 at 4:29pm
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. ;)
Last edited on Nov 27, 2012 at 4:32pm
Nov 27, 2012 at 4:32pm
It is usual practice for the object in which the pointer was instantiated to be responsible for destroying it.
Nov 27, 2012 at 4:44pm
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.
Last edited on Nov 27, 2012 at 4:50pm
Nov 27, 2012 at 4:47pm
@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.
Nov 27, 2012 at 4:57pm
> it is ok to do something like
> this->~MyClass(); new (this) MyClass(TheNewReference);
> in the assignment operator

Perhaps you should be using a std::reference_wrapper<> instead.
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper
Nov 27, 2012 at 5:04pm
I'd like to know how std::reference_wrapper<>::operator= is implemented :p
Nov 27, 2012 at 5:29pm
std::reference_wrapper<T> internally stores a pointer to T.
Though it exposes (copy constructible and copy assignable) reference semantics instead of pointer semantics.
Nov 27, 2012 at 5:40pm
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.
Nov 27, 2012 at 5:46pm
@JLB so it cheats. Which is fine, of course, :)
Topic archived. No new replies allowed.