After reading a question on the difference between pointers and references, I decided that I’d like to use references instead of pointers for my class fields. However it seems that this is not possible, because they cannot be declared uninitialized (right?).
In the particular scenario I’m working on right now, I don’t want to use normal variables (what’s the correct term for them by the way?) because they’re automatically initialized when I declare them.
In my snippet, bar1 is automatically instantiated with the default constructor (which isn’t what I want), &bar2 causes a compiler error because you can’t use uninitialized references (correct?), and *bar3 is happy as larry because pointers can be declared uninitialized (by the way, is it best practice to set this to NULL?).
class Foo { public: Bar bar1; Bar &bar2; Bar *bar3; }
It looks like I have to use pointers in this scenario, is this true? Also, what’s the best way of using the variable? The -> syntax is a bit cumbersome… Tough luck? What about smart pointers, etc? Is this relevant?
Update 1:
After attempting to implement a reference variable field in my class and initializing it in the constructor, why might I receive the following error?
../src/textures/VTexture.cpp: In constructor ‘vimrid::textures::VTexture::VTexture()’: ../src/textures/VTexture.cpp:19: error: uninitialized reference member ‘vimrid::textures::VTexture::image’
Here’s the real code:
// VTexture.h class VTexture { public: VTexture(vimrid::imaging::ImageMatrix &rImage); private: vimrid::imaging::ImageMatrix ℑ } // VTexture.cpp VTexture::VTexture(ImageMatrix &rImage) : image(rImage) { }
I’ve also tried doing this in the header, but no luck (I get the same error).
// VTexture.h class VTexture { public: VTexture(vimrid::imaging::ImageMatrix &rimage) : image(rImage) { } }
Update 2:
Fred Larson – Yes! There is a default constructor; I neglected it because I thought it wasn’t relevant to the problem (how foolish of me). After removing the default constructor I caused a compiler error because the class is used with a std::vector which requires there to be a default constructor. So it looks like I must use a default constructor, and therefore must use a pointer. Shame… or is it? 🙂
Answer to Question 1:
Right.
Answer to Question 2:
You initialize references of your class in your constructor’s initializer list:
Answer to Question 3:
There is no correct name for them, typically you can just say pointers for most discussions (except this one) and everything you need to discuss will also apply to references. You initialize non pointer, non reference members in the same way via the initailizer list.
Answer to Question 4:
They can be declared uninitialized yes. It is better to initialize them to NULL because then you can check if they are valid.
Answer to Question 5:
You can use either pointers or references, but references cannot be re-assigned and references cannot be NULL. A pointer is just like any other variable, like an int, but it holds a memory address. An array is an aliased name for another variable.
A pointer has its own memory address, whereas an array should be seen as sharing the address of the variable it references.
With a reference, after it is initialized and declared, you use it just like you would have used the variable it references. There is no special syntax.
With a pointer, to access the value at the address it holds, you have to
dereferencethe pointer. You do this by putting a * before it.Answer to Question 6:
Smart pointers (See boost::shared_ptr) are used so that when you allocate on the heap, you do not need to manually free your memory. None of the examples I gave above allocated on the heap. Here is an example where the use of smart pointers would have helped.
Answer to Question 7:
The problem is that you didn’t specify an initializer list. See my answer to question 2 above. Everything after the colon :