PDA

View Full Version : How to return a reference of a QPointer ?



jezz
4th February 2011, 12:21
Hi, I need to do something like this:


class Apple {
private:
QPointer<Tree> m_tree;
public:
Tree &tree();
}

Tree &Apple::tree()
{
return m_tree;
}


But the compiler says this for the line 'return m_tree':
error C2440: 'return' : cannot convert from 'QPointer<T>' to 'Tree &'

How to change the line to make it work?
Thanks.

Zlatomir
4th February 2011, 12:35
What "work" means, what are you trying to achieve.
Do you want to return a QPointer<Tree> or a dereferenced QPointer?

jezz
4th February 2011, 12:37
Thanks, just want to return a reference to m_tree.

mpalomas
4th February 2011, 12:38
What about something like :

return *m_tree;

According to the documentation here http://doc.qt.nokia.com/4.7/qpointer.html , operator* should return a reference.

Zlatomir
4th February 2011, 12:46
Why not returning the m_tree pointer? Since it's just a pointer not the whole object?
Always try to keep the code simple.

QPointer<Tree>Apple::tree()
{
return m_tree;
}

jezz
4th February 2011, 12:56
What about something like :

return *m_tree;

According to the documentation here http://doc.qt.nokia.com/4.7/qpointer.html , operator* should return a reference.

Thanks, this works.


Why not returning the m_tree pointer? Since it's just a pointer not the whole object?
Always try to keep the code simple.

QPointer<Tree>Apple::tree()
{
return m_tree;
}

Thanks, but the usage would look like this


QPointer<Tree> blah = apple->tree();


It is cleaner like this:


Tree blah = apple->tree();

Zlatomir
4th February 2011, 13:18
Well, you said you need the pointer when i asked the first question (what you are trying to achieve), i asked that because you were somewhere in the "middle" between the two solutions.

LE: for that you didn't really needed the reference return. Since you are coping the object you can return the value.

stampede
4th February 2011, 13:23
It is cleaner like this:

Tree blah = apple->tree();
You can always use typedef:

typedef QPointer<Tree> TreePtr;
TreePtr p = apple->tree();
Looks clean enough to me ;) And its just a pointer, so it does not require to copy the whole tree

jezz
4th February 2011, 13:35
Well, you said you need the pointer when i asked the first question (what you are trying to achieve), i asked that because you were somewhere in the "middle" between the two solutions.

LE: for that you didn't really needed the reference return. Since you are coping the object you can return the value.
I mean &m_tree (reference to m_tree), not pointer.



You can always use typedef:

typedef QPointer<Tree> TreePtr;
TreePtr p = apple->tree();
Looks clean enough to me ;) And its just a pointer, so it does not require to copy the whole tree
It would need lots of typedef if there are lots of pointers to different classes.

Zlatomir
4th February 2011, 13:45
I mean &m_tree (reference to m_tree), not pointer.

Q: Now you have a reference to m_tree? A: NO
You have a copy of a Tree object.

You use pointers or references to prevent the copy of whole objects when you pass them from one place to another.

stampede
4th February 2011, 13:50
Tree blah = apple->tree();
There is no difference here if tree() returns a reference or value, each time Tree::Tree(const Tree& t) copy constructor is invoked.
If you want to prevent copying, return a pointer or:

Tree& blah = apple->tree();


It would need lots of typedef if there are lots of pointers to different classes.
One per class, not that much :)

jezz
4th February 2011, 14:08
My bad, I should have put it this way :)


Tree& blah = apple->tree();

Zlatomir
4th February 2011, 15:14
Just be careful so that you don't end-up with "dangling" references.

The references can't be NULL (that is why some assume they are safer than pointers) but with the help of pointers they can get invalid...

aamer4yu
4th February 2011, 20:45
It is cleaner like this:
Qt Code:
Switch view

Tree blah = apple->tree();
Even if it is Tree& blah = apple->tree();
I would disagree it is cleaner code.
If you use pointers, you know you are modifying something which you haven't created. But in case of reference it is hard to know.

Also if references are returned, I would prefer to use it on left hand side. For eg if you have QList<int> numbers;
Then having a reference with [] operator,,,, I can assign value like - numbers[index] = 10;
Lets say I wrote code like -

int & temp = numbers[index];
...
... // assume you have many lines of code here...
temp = 10; // Can you still know you are actually modifying something ? oops ,, did you forget ?
// numbers[index] = 10; // with this line you know you are modifying something..

Rest depends on personal choice :)

SixDegrees
4th February 2011, 20:51
Uh - what's the point of this exercise? You declare m_tree private, but then you hand over a direct reference to it whenever the user asks. There's no point in making m_tree private in such a case, since you throw away privacy by passing back the object.

Here's a more sane solution that accomplishes exactly the same thing with far less code: make m_tree public and access it directly via apple.m_tree. There's no difference between that and the far more convoluted constructs you're wrestling with above.