Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Returning a pointer to a struct

Reply
Thread Tools

Returning a pointer to a struct

 
 
eriwik@student.chalmers.se
Guest
Posts: n/a
 
      12-01-2006
On Dec 1, 12:09 am, (E-Mail Removed) wrote:
> Hey all,
>
> I want to return a pointer to a struct. Here is what I'lm trying to do:
>
> struct Position{
> int x;
> int y;
>
> };Position* GraphicTag::getRenderCentre(){
> int cenx = m_renderPosition->x + m_size->width / 2;
> int ceny = m_renderPosition->y + m_size->height / 2;
>
> return (Position *){cenx,ceny}; // <---- Error here
>
> }I get "Error: initializer for scalar variable requires one element".
> I'm a Java programmer at heart, and still a little uneasy around
> pointers.


I'd just like to add, if you haven't figured it out already, that in
principle there are two instances where you can return a pointer. The
first is if you have a class/struct with a member, then you can return
a pointer to that member, but as Salt_Peter has pointed out, this is
generally not a good idea. The second instance is when you dynamically
allocate memory for some type, in which case you get a pointer:

Position* GraphicTag::getRenderCentre(){
Position* pos = new Position; // OBS!
pos->x = m_renderPosition->x + m_size->width / 2;
pos->y = m_renderPosition->y + m_size->height / 2;

return pos;
}

As others have pointed out, this is generally a bad idea, the memory
allocated by new will not get freed until you call delete on a
Position-pointer that points to it (like the one returned from
getRenderCentre()), should you loose this pointer you have a
memory-leek. In general, every new shall have a delete, the problem is
that you only call new in one place but you often might need to delete
in several places. This leads to two problems, either you don't delete
where you should, and you get a memory-leek, or you try to use a
pointer that has already deleted, in which case (if you are lucky) the
program will crash (if you are unlucky anything could happen).

--
Erik Wikström

 
Reply With Quote
 
 
 
 
Steve Pope
Guest
Posts: n/a
 
      12-01-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:

>I'd just like to add, if you haven't figured it out already, that in
>principle there are two instances where you can return a pointer. The
>first is if you have a class/struct with a member, then you can return
>a pointer to that member, but as Salt_Peter has pointed out, this is
>generally not a good idea. The second instance is when you dynamically
>allocate memory for some type, in which case you get a pointer:


Actually, there's a third situation when you can return a pointer:
it can point to a static or global object. That's in a sense
the safest type of pointer to return.

Steve
 
Reply With Quote
 
 
 
 
djcredo@gmail.com
Guest
Posts: n/a
 
      12-01-2006
Wow, this has been a very enlightening thread, thank you all who have
made time to post and write code examples!

Every new user should read this thread - many C++ books / tuts tell you
how to "code", but don't tell you how to "build software" if you know
what I mean. Rules like this should be committed to memory.

I have one final question if you would:

I have a class GraphicTag which has a member of type Tag (a class, not
struct). Both the Tag and GraphicTag objects are created in the main()
function, then the Tag is passed to the GraphicTag constructor:

int main(){

Tag tag(10,5);
GraphicTag gTag(// pass tag here to constructor);

}

My question is, how is it best to store the Tag inside the GraphicTag,
and hence, how is it best to pass it in the constructor? The Tag object
won't be changed inside the main() function; once it's passed to the
GraphicTag, it is left alone from the main() function's point of view.
Is it possible to do this:

int main(){
Tag* tag = new Tag(10,5);
GraphicTag gTag(tag);
}

class GraphicTag {
protected:
Tag m_tag;
};

GraphicTag::GraphicTag(Tag* tag){
m_tag = *tag; // m_tag is now the instance of the
created tag.
}

.... and is this even the best way?

Thanks again,
Matt

 
Reply With Quote
 
eriwik@student.chalmers.se
Guest
Posts: n/a
 
      12-01-2006
On Dec 1, 11:13 am, (E-Mail Removed) wrote:
> Wow, this has been a very enlightening thread, thank you all who have
> made time to post and write code examples!
>
> Every new user should read this thread - many C++ books / tuts tell you
> how to "code", but don't tell you how to "build software" if you know
> what I mean. Rules like this should be committed to memory.
>
> I have one final question if you would:
>
> I have a class GraphicTag which has a member of type Tag (a class, not
> struct). Both the Tag and GraphicTag objects are created in the main()
> function, then the Tag is passed to the GraphicTag constructor:
>
> int main(){
>
> Tag tag(10,5);
> GraphicTag gTag(// pass tag here to constructor);
>
> }My question is, how is it best to store the Tag inside the GraphicTag,
> and hence, how is it best to pass it in the constructor? The Tag object
> won't be changed inside the main() function; once it's passed to the
> GraphicTag, it is left alone from the main() function's point of view.
> Is it possible to do this:
>
> int main(){
> Tag* tag = new Tag(10,5);
> GraphicTag gTag(tag);
>
> }class GraphicTag {
> protected:
> Tag m_tag;
>
> };GraphicTag::GraphicTag(Tag* tag){
> m_tag = *tag; // m_tag is now the instance of the
> created tag.
>
> }... and is this even the best way?


You could, but once again, a pointer is not the best way to do it.
There are two "problems" with this approach, first you use dynamic
allocated memory (new) when you don't have to, the second is that if
the tag created in main() won't change, you don't have to store a copy
of it in GraphicTag, you can store the thing itself (or rather a
reference to it).

class GraphicTag {
protected:
Tag& m_tag; // notice the &, a reference
};

GraphicTag::GraphicTag(Tag& tag){
m_tag = tag; // m_tag is now a reference to the tag
created in main
}

int main(){
Tag tag(10,5);
GraphicTag gTag(tag);
}

Read up on references, they can often be used where a pointer can be
used, and in those cases a reference is almost always preferable. A
note on style: try to keep at least the closing '}' on a separate line,
it will make the code easier to read.

--
Erik Wikström

 
Reply With Quote
 
eriwik@student.chalmers.se
Guest
Posts: n/a
 
      12-01-2006
On Dec 1, 11:39 am, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
A
> note on style: try to keep at least the closing '}' on a separate line,
> it will make the code easier to read.


Disregard that, seems it's only google messing up the code.

--
Erik Wikström

 
Reply With Quote
 
djcredo@gmail.com
Guest
Posts: n/a
 
      12-01-2006
Thank you, I am now much more clued-in about pointers and references. I
am very greatful! I will aim to use references much more now (I had
completely overlooked them and just jumped into pointers)!

Thanks again,
Matt

 
Reply With Quote
 
Gavin Deane
Guest
Posts: n/a
 
      12-01-2006

(E-Mail Removed) wrote:
> I have a class GraphicTag which has a member of type Tag (a class, not
> struct). Both the Tag and GraphicTag objects are created in the main()
> function, then the Tag is passed to the GraphicTag constructor:
>
> int main(){
>
> Tag tag(10,5);
> GraphicTag gTag(// pass tag here to constructor);
>
> }
>
> My question is, how is it best to store the Tag inside the GraphicTag,
> and hence, how is it best to pass it in the constructor? The Tag object
> won't be changed inside the main() function; once it's passed to the
> GraphicTag, it is left alone from the main() function's point of view.


What do you mean by "it is left alone from the main() function's point
of view"? Do you mean main does not touch the Tag object, does not
change it, does not pass it to any other functions or objects, does not
care in any way about it after the GraphicTag is created? If so, then
the Tag is logically owned by the GraphicTag and should not even exist
in main.

class Tag
{
public:
Tag(int a, int b) {}
// ...
};

class GraphicTag
{
public:
GraphicTag(int tag_param_1, int tag_param_2) :
tag(tag_param_1, tag_param_2) {}
// ...
private:
Tag tag;
// ...
};

int main()
{
GraphicTag gTag(10, 5);
}

Gavin Deane

 
Reply With Quote
 
Gavin Deane
Guest
Posts: n/a
 
      12-01-2006

(E-Mail Removed) wrote:
> Read up on references, they can often be used where a pointer can be
> used, and in those cases a reference is almost always preferable.


As long as that doesn't contradict the ownership semantics of the
design. I saw nothing in the original question to suggest that the
simplest solution, holding a member object rather than holding a
reference or pointer, was inappropriate.

Gavin Deane

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Struct pointer vs. struct array pointer aleksa C Programming 16 02-20-2013 08:20 PM
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
(: Pointer to struct withing pointer to struct :) Zero C Programming 16 11-19-2005 01:27 AM
passing pointer->struct->pointer->struct to function. .. ?? beetle C Programming 2 01-25-2005 06:08 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments