0

Why to use references rather than pointers when there is no compile time type checking on references?

Imagine that you are creating an object of type Person that needs to hold a reference/pointer to their House (pretty random) - so the person object would hold the house reference/pointer as a data member. Imagine this was done with references:

class Person{
   public:
      Person(House& myHouse) : house(myHouse) { }
   private:
      House& house;
};

The issue I see though is if you forget to include the & in the data member declaration that thing you thought was a reference becomes a copy. Surely it would be safer to pass and save a pointer so this error would be flagged up at compile time?

I'm not making a point to use one or the other - I'm asking why are references used over pointers to save data members?

LihO
  • 41,190
  • 11
  • 99
  • 167
Armada
  • 718
  • 8
  • 19
  • 2
    That code isn't legal. The member reference was not initialized in the construction initializer list. – WhozCraig Feb 23 '13 at 21:22
  • 1
    The snippet you attached is not valid C++ code. Reference **MUST** be initialized with an existing object. – LihO Feb 23 '13 at 21:22
  • How is passing a pointer safer than what you have now? In fact, the problem you *just exhibited prior to your edit* (failure to initialize your reference in the initializer list) would *not* be caught by the compiler if your member was a pointer. – WhozCraig Feb 23 '13 at 21:26
  • *"The issue I see though is if you forget to include the & in the data member declaration that thing you thought was a reference becomes a copy"* - If you "forget" then you are probably a beginner, and this will be a learning experience for you. I mean, it *could* happen to a more experienced dev, but I can't remember the last time I "forgot" to take a reference when that's what I wanted. – Ed S. Feb 23 '13 at 21:43
  • I am a beginner and I now see the use of having a reference data member - if it MUST not be null and it MUST NOT change. – Armada Feb 23 '13 at 21:54
  • 2
    @Frammo Then you learned something today and got wiser thanks to SO. ;) – Öö Tiib Feb 23 '13 at 22:01
  • @Frammo: Just be careful of stale references, i.e., initializing the reference with an object that goes out of scope before you're object does. – Ed S. Feb 23 '13 at 22:28
  • By the way, there's a possible duplicate: [Should I prefer pointers or references in member data?](http://stackoverflow.com/q/892133/1168156) – LihO Feb 23 '13 at 23:01

2 Answers2

0

if you forget to include the & in the data member declaration that thing you thought was a reference becomes a copy... it would be safer to pass and save a pointer so this error would be flagged up at compile time?

You can't just forget to type & sign when declaring a member. Whether you write House& house or House house is a decision of yours, that compiler should respect. When you change declaration of a reference to an object, you do it intentionally. It is not something that your compiler should warn you about.

There is no way how a compiler could know whether you intent to pass by value or by a reference. When you change passing by pointer to passing by value, compiler reports an error only because you treat a copy (an object with automatic storage duration) as a pointer (which is syntactically incorrect) and not because it would be able to recognize, that you probably meant to pass by a pointer.

why are references used over pointers to save data members?

The main reason is ensuring that the reference will be always initialized with an existing object, which also implies no NULL-check error handling and catching the possible errors at compile type rather than run time. Other arguments might be cleaner code (readability) and in my opinion, using of references also induces people to rely on objects with automatic storage duration and learn to follow RAII idiom rather than entering the dungeons of ugly memory management and memory leaks.

But I'm sure you'll find many existing questions addressing this question, e.g. Pointer vs. Reference

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
0

I'm not making a point to use one or the other - I'm asking why are references used over pointers to save data members?

Both pointers and references are used as data members. Reference T& is as flexible as immutable pointer T* const. Additionally reference may not be null. So if those properties are describing what you need in the best way then use reference.

IOW, if every Person must have a House and Person may not switch to other House during Person's lifetime then use reference. Apparently both premises feel ridiculous so pointer is actually likely better.

Pointer is not always better. Favor immutability (int* const) to mutability (int*) when things stay immutable. Favor certainty (exactly one) to uncertainty (one or none) when things are certain.

In OOP the composition relation in component object is usually done as reference to composite object. A component can not exist without composite and can not become component of other composite so reference is best.

Öö Tiib
  • 10,809
  • 25
  • 44
  • *"if every `Person` must have a `House` and `Person` may not switch to other `House` during `Person`'s lifetime then use reference"* - **no**. It means that the object of type `House` must exist before the object of type `Person` is being constructed and that no matter what happens, the original object of type `House` that object of type `Person` refers to should be changed rather than reassigned to another object of type `House`. In other words: **Pointer vs. Reference is not a decision affected by the design of your data model**. – LihO Feb 23 '13 at 22:42
  • @LihO care to explain the case ... how can someone have house that does not change during his lifetime unless that house did exist before he did born? Pointer vs. Reference has everything to do with relation type between the objects. – Öö Tiib Feb 23 '13 at 22:46
  • *"how can someone have house that does not change during his lifetime"* - that's exactly my point. Reference will not refer to different object, but it doesn't mean that the object it refers to can not change. – LihO Feb 23 '13 at 23:02
  • @Liho i meant "change" in sense "switch with other House" not in sense "paint House with different color". My answer contains the wording. – Öö Tiib Feb 23 '13 at 23:04
  • Imagine this method of `Person`: `void moveTo(House& newHouse){ house = newHouse; }` – LihO Feb 23 '13 at 23:12
  • @LihO You apparently did not read my answer? The premise that person can not switch to other house is ridiculous. So I said that pointer is better. About mutability of house I said nothing. – Öö Tiib Feb 23 '13 at 23:14
  • I'm taking back the downvote, but check this code: http://ideone.com/pCm8mO that shows how `House a` might actually become a `House b` by using reference. – LihO Feb 23 '13 at 23:18
  • @Liho In your example you are mutating the house similar to other house by assignment (painting it same color). They still stay different objects in sense of C++ (different storage locations). – Öö Tiib Feb 23 '13 at 23:26
  • But we were talking about data model... so even when you use ORM and you will have object of type `House` representing one row from `house` table (id, address, whatever) and `Person` holding a reference to this house, you can still change this object by using attributes of another object (including id) so at abstraction level of data model: `Person` will move to different house (different DB record). – LihO Feb 23 '13 at 23:29
  • @Liho It does not work like that. You can rebuild your house to look like house of your uncle. That does not mean that you live in same house as your uncle. You have to share exactly same house with uncle then you live in same house with uncle. – Öö Tiib Feb 23 '13 at 23:32