473,770 Members | 4,443 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Return appropriately by value, (smart) pointer, or reference

Posted to comp.lang.c++.m oderated with little response. Hoping for
better from the unmoderated groups:

-------- Original Message --------
Subject: Return appropriately by value, (smart) pointer, or reference
Date: 27 Aug 2005 15:13:23 -0400
From: Neal Coombes <ne***@trdlnk.c om>
Organization: Aioe.org NNTP Server
To: (Usenet)
Newsgroups: comp.lang.c++.m oderated

I think I already know how to write such a coding standard item, but I'm
very interested in finding out the right answer. :)

In Herb and Andrei's Coding Standards book Item 25 is about taking
parameters appropriately by value, (smart) pointer, or reference. There
is however no item about how to return.

So If anyone is up for it, I'd be very interested in how to write Item
25b. Return appropriately by value, (smart) pointer, or reference.

Thanks,

Neal

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Sep 15 '05 #1
5 3044
* Don't return references or pointers to function-local data. They
will be destroyed by the time the calling function can access them

* Return a smart pointer if you need to return a new'd object that may
not be checked for by the calling function. Ex

MyObject* MyFancyFunction (std::string& s)
{
// ...
return new MyObject(<some data>);
}

// in calling function:
MyFancyFunction (); // oops! The allocated MyObject is now
lost forever

Instead do:

std::auto_ptr<M yObject> MyFancyFunction (std::string& s)
{
// ...
return std::auto_ptr<M yObject>(new MyObject(<some data>));
}

// in calling function:
MyFancyFunction (); // phew! auto_ptr will now delete the
object for me if I don't need it

* Returning by reference usually doesn't make a lot of sense. In
non-class functions, you don't want to return a reference to a local
variable. In non-class functions, references can be passed in --
usually you don't have to return that reference, just modify the value
of the variable being referenced. In class-functions, it's considered
good practice to use get/set methods instead of returning a reference
to a private member. That way, if you need to abstract the private
member, you can do so more easily.

* When pointers and references don't make sense, return by value.

Sep 15 '05 #2
Neal Coombes wrote:
In Herb and Andrei's Coding Standards book Item 25 is about taking
parameters appropriately by value, (smart) pointer, or reference.
There is however no item about how to return.

So If anyone is up for it, I'd be very interested in how to write
Item 25b. Return appropriately by value, (smart) pointer, or
reference.


I'll try to answer the question you've asked in a moment, but I think
the issue is deeper than this.

There are several other ways to get data out of a function. At the very
least, you have to consider exceptions, "out" parameters, and shared
data areas like the state of an object. On top of those, there are more
devious variations on the theme, such as passing in a function object or
using call-backs.

In addition, return values in C++ can provide only a single piece of
information. To return more, we must either use a compound type like a
struct or tuple object, or we must use other mechanisms to supplement or
replace the return value.

In other words, return values do not operate in a vacuum. The best use
for them can depend intimiately on what other approaches are
(potentially) being used as well.

With that caveat out of the way, here are a few guidelines that come to
mind immediately.
1. By default, return by value. This provides natural semantics, and
minimal scope for misunderstand or misuse.

1a. Help your optimiser to make this as efficient as possible. IIRC,
Scott Meyers wrote on this subject in one of his Effective books.

1b. Choose another technique with polymorphic types, to avoid slicing.

1c. Emphasise readability at the point where your function is called.

1ci. If your function's primary purpose is to return some data, name it
after that data.

1cii. Avoid "out" parameters where a return value could be used instead.

It's cumbersome to write this:
SomeType data;
GetDataInto(dat a);
DoSomethingWith (data);
when you could write this:
DoSomethingWith (Data());

1d. If a returned value is likely to be an intermediate step in a
computation, consider returning placeholder objects and using expression
template techniques to improve effiency.

2. Return a reference where a specific item of internal data should be
directly accessible, as with [] operators for data structures. Also
return a reference from operators that can be chained, such as
assignment operators and insertion/extraction for I/O streams.

2a. Provide versions for const, non-const or both, as appropriate.

2b. Be clear about what conditions invalidate the reference.
3. If you're returning any pointer type, smart or otherwise, be clear
whether a NULL value is possible, and what its significance is if so.
4. Raw pointers are ambiguous about intent, and are best avoided.
5. Where you want to return a pointer to a dynamically allocated object,
or an object of a polymorphic type, use a suitable smart pointer type to
ensure that ownership is transferred or shared as appropriate while
preserving the polymorphic behaviour. At least use an auto_ptr to make
sure ignoring a return value can't create an inadvertent memory leak.
Specify the ownership policy in a comment if it isn't clear from the code.
6. Where you're identifying a particular location in a data structure,
an iterator or some sort of key value may be a more powerful way to
return the information. If a pointer would provide uncontrolled access
to (part of) an array, returning a proxy object to represent that array
slice can provide range-checking for safety, while still offering almost
direct access to the underlying data structure for performance.
I'm sure these could be rearranged into something rather better written
and I'm sure there are omissions, but that's the starting point my
stream of consciousness came up with.

Hope that helps,
Chris
Sep 16 '05 #3
In article <11************ **********@z14g 2000cwz.googleg roups.com>,
ke********@moti oneng.com writes
* Don't return references or pointers to function-local data. They
will be destroyed by the time the calling function can access them

* Return a smart pointer if you need to return a new'd object that may
not be checked for by the calling function. Ex

MyObject* MyFancyFunction (std::string& s)
{
// ...
return new MyObject(<some data>);
}

// in calling function:
MyFancyFunction (); // oops! The allocated MyObject is now
lost forever

Instead do:

std::auto_ptr<M yObject> MyFancyFunction (std::string& s)
{
// ...
return std::auto_ptr<M yObject>(new MyObject(<some data>));
}

// in calling function:
MyFancyFunction (); // phew! auto_ptr will now delete the
object for me if I don't need it

* Returning by reference usually doesn't make a lot of sense. In
non-class functions, you don't want to return a reference to a local
variable. In non-class functions, references can be passed in --
usually you don't have to return that reference, just modify the value
of the variable being referenced. In class-functions, it's considered
good practice to use get/set methods instead of returning a reference
to a private member. That way, if you need to abstract the private
member, you can do so more easily.

* When pointers and references don't make sense, return by value.

Returning references to static and member data by const reference makes
a great deal of sense when the data is relatively large. Returning an
item by reference that has been passed in as a reference parameter is
also sensible if you want to use the function as part of a larger
expression.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
Sep 16 '05 #4
Thanks for the Help guys. I'll go off and try to write such an item for
my companies coding standard, and post it here (in a new thread) for
more feedback.

Neal
Sep 19 '05 #5
That's why I said "usually".

Sep 22 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
1806
by: Johnny Hansen | last post by:
Hello, I've been trying to implement smart pointers in C++ (combined with a reference counter) because I want to do some memory management. My code is based on the gamedev enginuity articles, various books and ... whatever I could find on the subject :-) I'll leave out the reference counter part because its pretty basic, but my reference counter class is called xObject. My smart pointer class is called xPointer.
9
2155
by: christopher diggins | last post by:
I would like to survey how widespread the usage of smart pointers in C++ code is today. Any anecdotal experience about the frequency of usage of smart pointer for dynamic allocation in your own code or other people's code you have come across would be appreciated. I am also trying to identify the likelihood nad frequency of scenarios where smart pointer solutions would not be appropriate, i.e. for some reason such as performance or...
16
3204
by: Bob Hairgrove | last post by:
Consider the classic clone() function: class A { public: virtual ~A() {} virtual A* clone() const = 0; }; class B : public A { public:
13
2275
by: pauldepstein | last post by:
My texts give plenty of examples where passing by reference is necessary. For instance, the famous swap example. However, I've never seen an example where passing a variable by value is necessary. One place where I've seen passing by value recommended is in the throwing of exceptions. However, my texts never say why throwing by reference is wrong. (Of course, lots of people have explained why catching by value is poor practice.) ...
14
18209
by: Ian | last post by:
I am looking at porting code from a C++ application to C#. This requires implementing data sharing functionality similar to what is provided by a smart pointer in C++. I have only recently begun to work in C# and am asking for suggestions/comments of how to implement a similar data sharing technique in C#. A C++ smart pointer can be used to share common information. For example, assume information managed by objects I1, I2, I3,...
33
5083
by: Ney André de Mello Zunino | last post by:
Hello. I have written a simple reference-counting smart pointer class template called RefCountPtr<T>. It works in conjunction with another class, ReferenceCountable, which is responsible for the actual counting. Here is the latter's definition: // --- Begin ReferenceCountable.h ---------- class ReferenceCountable
14
20411
by: Abhi | last post by:
I wrote a function foo(int arr) and its prototype is declared as foo(int arr); I modify the values of the array in the function and the values are getting modified in the main array which is passed also. I understand that this way of passing the array is by value and if the prototype is declared as foo(int *), it is by reference in which case the value if modified in the function will get reflected in the main function as well. I dont...
68
4649
by: Jim Langston | last post by:
I remember there was a thread a while back that was talking about using the return value of a function as a reference where I had thought the reference would become invalidated because it was a temporary but it was stated that it would not. This has come up in an irc channel but I can not find the original thread, nor can I get any code to work. Foo& Bar( int Val ) { return Foo( Val ); }
50
4512
by: Juha Nieminen | last post by:
I asked a long time ago in this group how to make a smart pointer which works with incomplete types. I got this answer (only relevant parts included): //------------------------------------------------------------------ template<typename Data_t> class SmartPointer { Data_t* data; void(*deleterFunc)(Data_t*);
0
10237
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10071
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9882
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8905
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7431
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5326
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5467
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3987
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.