Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Return pointers or references?

Reply
Thread Tools

Return pointers or references?

 
 
Gama Franco
Guest
Posts: n/a
 
      08-19-2004
Hi,

I'm designing an interface for a shared library, and I would like to
know if there is a standard about how to return an object to the user. I
will use exceptions to report errors, so there are at least four ways to
do it.

For example if we have a method named M, that receives a reference to
parameter p and returns object o.

1 - virtual o& M(p& parameter) throw(Exception1, Exception2...

2 - virtual o* M(p& parameter) throw(Exception1, Exception2...

3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
Exception2...

4 - virtual void M(p& parameter, o* returnVal) throw(Exception1,
Exception2...


Probably there is no convention about it and is only a mater of taste,
but I would like to know some opinions.

Best regards,
Gama Franco

 
Reply With Quote
 
 
 
 
E. Robert Tisdale
Guest
Posts: n/a
 
      08-19-2004
Gama Franco wrote:
>
> I'm designing an interface for a shared library,
> and I would like to know
> if there is a standard about how to return an object to the user. I
> will use exceptions to report errors,
> so there are at least four ways to do it.
>
> For example if we have a method named M,
> that receives a reference to parameter p and returns object o.
>
> 1 - virtual o& M(p& parameter) throw(Exception1, Exception2...
>
> 2 - virtual o* M(p& parameter) throw(Exception1, Exception2...
>
> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
> Exception2...
>
> 4 - virtual void M(p& parameter, o* returnVal) throw(Exception1,
> Exception2...
>
>
> Probably there is no convention about it and is only a matter of taste,
> but I would like to know some opinions.


None of the above.
Use

virtual o M(const p& parameter) const;

instead. Pass by *const* reference and return by value.
 
Reply With Quote
 
 
 
 
Phlip
Guest
Posts: n/a
 
      08-19-2004
Gama Franco wrote:

> I'm designing an interface for a shared library, and I would like to
> know if there is a standard about how to return an object to the user. I
> will use exceptions to report errors, so there are at least four ways to
> do it.
>
> For example if we have a method named M, that receives a reference to
> parameter p and returns object o.
>
> 1 - virtual o& M(p& parameter) throw(Exception1, Exception2...
>
> 2 - virtual o* M(p& parameter) throw(Exception1, Exception2...
>
> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
> Exception2...
>
> 4 - virtual void M(p& parameter, o* returnVal) throw(Exception1,
> Exception2...
>
>
> Probably there is no convention about it and is only a mater of taste,
> but I would like to know some opinions.


Smart pointers?

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-19-2004
Gama Franco wrote:
> I'm designing an interface for a shared library, and I would like to
> know if there is a standard about how to return an object to the user. I
> will use exceptions to report errors, so there are at least four ways to
> do it.


More, actually. You still can return by value. And often that is
the preferred method. You can pass a pointer to an object by reference
and you can pass a pointer to an object by pointer.

> For example if we have a method named M, that receives a reference to
> parameter p and returns object o.


If it "returns object o", why are you trying to return a pointer or
a reference? Doesn't "returns object" mean "by value"?

>
> 1 - virtual o& M(p& parameter) throw(Exception1, Exception2...
>
> 2 - virtual o* M(p& parameter) throw(Exception1, Exception2...
>
> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
> Exception2...
>
> 4 - virtual void M(p& parameter, o* returnVal) throw(Exception1,
> Exception2...
>
>
> Probably there is no convention about it and is only a mater of taste,
> but I would like to know some opinions.


The differences are significant. First of all, you clearly returning
a pointer or a reference to a _non_const_ object. Where is that object
residing? Is it part of the object for which the member function 'M'
is called? Then returning a reference or a pointer is often OK, but
the lifetime of the "returned" object will depend on the lifetime of
the object for which you call 'M'. So, there is a dependency, which
many prefer to avoid.

Second, a pointer can be null, so any time somebody returns a pointer
to me, I need to write code to verify that it's valid. A reference can
never be null, no matter what some of your college buddies say. So,
here is one important difference. Another difference is that it's much
easier to deal with pointers if they are to a dynamically created object.
No, it's not impossible to work with a reference in that case

int &ir = *(new int(42));
delete &ir;

but it's ugly. So, if you're creating an object in free store, return
a pointer. Also, thoroughly document that fact so that the user won't
forget to dispose of the object properly (in the case of returning by
value there is no disposal headache).

Cases 3 and 4 assume that (a) the object exists outside and (b) its type
provides some kind of assignment semantics. In that case, you have more
of a question "what's the preferred way of passing objects into functions"
and not "what's the preferred way of returning objects". So, it's quite
different from the first two.

You could merge the cases 3 and 4 into "pass a pointer to an object by
reference" so that you could change it inside the function to point to
something meaningful. In that case the user doesn't have to create
an object before calling your function and you can return the address of
something allocated dynamically. You cannot have a reference to another
reference, so there is only one more case you didn't mention: pass
a pointer to a pointer:

virtual void M(p& parameter, o** returnValPtr) throw(Exception1, ..

which is not bad, but the same implication applies: _you_ need to check
that I didn't pass a null pointer to you, and when the function returns,
I have to check that the value of 'returnValPtr' is not null before I
can use the object.

Victor
 
Reply With Quote
 
Gama Franco
Guest
Posts: n/a
 
      08-20-2004
E. Robert Tisdale wrote:
> Gama Franco wrote:
>
>>
>> I'm designing an interface for a shared library, and I would like to
>> know if there is a standard about how to return an object to the user.
>> I will use exceptions to report errors, so there are at least four
>> ways to do it.
>>
>> For example if we have a method named M, that receives a reference to
>> parameter p and returns object o.
>>
>> 1 - virtual o& M(p& parameter) throw(Exception1, Exception2...
>>
>> 2 - virtual o* M(p& parameter) throw(Exception1, Exception2...
>>
>> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
>> Exception2...
>>
>> 4 - virtual void M(p& parameter, o* returnVal) throw(Exception1,
>> Exception2...
>>
>>
>> Probably there is no convention about it and is only a matter of
>> taste, but I would like to know some opinions.

>
>
> None of the above.
> Use
>
> virtual o M(const p& parameter) const;
>
> instead. Pass by *const* reference and return by value.

Hi,

I forgot to mention something very important. One of the requisites is
efficiency. I mean, the API should run as fast as possible (it deals
with scientific data aquisition).

That is the reason why I only placed the return value as a reference or
a pointer.

Thanks in advance,
Gama Franco

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-20-2004
"Gama Franco" <(E-Mail Removed)> wrote...
> [..]
> I forgot to mention something very important. One of the requisites is
> efficiency. I mean, the API should run as fast as possible (it deals
> with scientific data aquisition).
>
> That is the reason why I only placed the return value as a reference or
> a pointer.


You didn't mention how you'd be using the returned value or how you'd
be calling your functions.

V


 
Reply With Quote
 
Niels Dybdahl
Guest
Posts: n/a
 
      08-20-2004
> >> I'm designing an interface for a shared library, and I would like to
> >> know if there is a standard about how to return an object to the user.
> >> I will use exceptions to report errors, so there are at least four
> >> ways to do it.
> >>
> >> For example if we have a method named M, that receives a reference to
> >> parameter p and returns object o.
> >>
> >> 1 - virtual o& M(p& parameter) throw(Exception1, Exception2...
> >>
> >> 2 - virtual o* M(p& parameter) throw(Exception1, Exception2...
> >>
> >> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
> >> Exception2...
> >>
> >> 4 - virtual void M(p& parameter, o* returnVal) throw(Exception1,
> >> Exception2...
> >>
> >>
> >> Probably there is no convention about it and is only a matter of
> >> taste, but I would like to know some opinions.

> >
> >
> > None of the above.
> > Use
> >
> > virtual o M(const p& parameter) const;
> >
> > instead. Pass by *const* reference and return by value.

> Hi,
>
> I forgot to mention something very important. One of the requisites is
> efficiency. I mean, the API should run as fast as possible (it deals
> with scientific data aquisition).


As mentioned virtual o M(...) is the most elegant solution. Often the
implemention is that the caller allocates the memory for o and M initializes
it with its return statement, which often defaults to a simple copy
operation. If you want to get rid of the construction, copying and
desctruction of the object for each call, you hae to use method 3 or 4. They
are equal in terms of efficiency. Whether you use pointer or reference does
not matter in terms of effiency. I prefer using references to emphasize,
that it is not an array.
Your methods 1 and 2 have the usual problems related to allocation and
deallocation:
- An often made mistake is to return a local object, which goes out of scope
when the function terminates.
- It is not clear who is the owner of the objects returned. If they are
owned by a vector, then the caller should not clean them up. Otherwise it
might be the task of the caller to clean them up. Or there might be some
deallocation function in the library...
Usually I use method 1 and 2 only when the objects are owned by some list or
vector, where method 3 and 4 are less efficient.

Niels Dybdahl


 
Reply With Quote
 
Bart Blommerde
Guest
Posts: n/a
 
      08-20-2004
>> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
>> Exception2...


Is it fair to say that, following your reasoning, this is generally the
best option of the four? Maybe it's more a matter of personal coding
style than of following accepted standards, but :

1.The returnVal is completely 'managed' by the client. So :
- There's no danger of a member function lifting an object outside
it's scope (as in option 1).
- There's no need documenting that the allocated object should be freed
by the client (as in option 2).
2.returnVal doesn't have to be checked for the null value
(as in option 2 + 4).
3.Use of pointers is avoided, which is always good for readability.



Bart

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-20-2004
Bart Blommerde wrote:
>>> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
>>> Exception2...

>
>
> Is it fair to say that, following your reasoning, this is generally the
> best option of the four? Maybe it's more a matter of personal coding
> style than of following accepted standards, but :
>
> 1.The returnVal is completely 'managed' by the client. So :
> - There's no danger of a member function lifting an object outside
> it's scope (as in option 1).
> - There's no need documenting that the allocated object should be freed
> by the client (as in option 2).
> 2.returnVal doesn't have to be checked for the null value
> (as in option 2 + 4).
> 3.Use of pointers is avoided, which is always good for readability.


Out of four presented, yes, probably. Out of all available, questionable.
I'd still return by value and let the compiler optimise the hell out of
it all. It's just semantically clearer. When you write

SomeClass someObject(blah); // define+initialise
...
someOtherObject.M(someParameter, someObject);

(which is what you're expected to do in the case 3) it is unclear for the
reader what's happening. For all we know, M is a void member (that's true
according to the case 3 declaration) that takes 2 arguments (that's also
true) and does something to the object 'someOtherObject', and not to its
second argument.

V
 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      08-20-2004
In article <(E-Mail Removed)>,
Gama Franco <(E-Mail Removed)> wrote:

> E. Robert Tisdale wrote:
> > Gama Franco wrote:
> >
> >>
> >> I'm designing an interface for a shared library, and I would like to
> >> know if there is a standard about how to return an object to the user.
> >> I will use exceptions to report errors, so there are at least four
> >> ways to do it.
> >>
> >> For example if we have a method named M, that receives a reference to
> >> parameter p and returns object o.
> >>
> >> 1 - virtual o& M(p& parameter) throw(Exception1, Exception2...
> >>
> >> 2 - virtual o* M(p& parameter) throw(Exception1, Exception2...
> >>
> >> 3 - virtual void M(p& parameter, o& returnVal) throw(Exception1,
> >> Exception2...
> >>
> >> 4 - virtual void M(p& parameter, o* returnVal) throw(Exception1,
> >> Exception2...
> >>
> >>
> >> Probably there is no convention about it and is only a matter of
> >> taste, but I would like to know some opinions.

> >
> >
> > None of the above.
> > Use
> >
> > virtual o M(const p& parameter) const;
> >
> > instead. Pass by *const* reference and return by value.

> Hi,
>
> I forgot to mention something very important. One of the requisites is
> efficiency. I mean, the API should run as fast as possible (it deals
> with scientific data aquisition).
>
> That is the reason why I only placed the return value as a reference or
> a pointer.


Yet you are making the function virtual? Try returning the object by
const value first, if profiling shows this is actually a problem (highly
unlikely IMO) then change it to const reference. No other code will need
to change in this case.
 
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
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
what value does lack of return or empty "return;" return Greenhorn C Programming 15 03-06-2005 08:19 PM
c++: pointers to pointers A C++ 3 10-29-2003 01:15 PM
pointers to pointers // exception handling error muser C++ 3 09-18-2003 06:19 PM
Template specialization of pointers with function pointers Phil C++ 1 09-16-2003 02:17 AM



Advertisments