Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Polymorphism AND return-by-value -vs- return-by-reference

Posted on 1997-05-23
5
Medium Priority
?
540 Views
Last Modified: 2008-03-10
I am a relatively new "convert" to the virtues of
polymorphism. I do design/development in both C++
and Java. One of the things that made a lot of sense
for us to include in our set of C++ classes that
we are building/using, is a virtual toString()
method. This obviously gives us the ability to
very generically write:

    object.toString()

anytime, anywhere. Using a base class reference or
pointer to an object, the correct toString() method
is called producing the appropriate output for the
particular object.

This is all well and good BUT the nagging question I am
wrestling with (being an old C/Assembler programmer) is
whether to return the string by reference or by value???
The C/Assembler part of me says I should be returning
strings by reference. But there are times when this may
not be appropriate.

Firstly, use of an object's toString() method or in
smalltalk-speak, sending a "to-string" message to an
object, is like asking an object to produce the string
form of itself.

An object may or may not include an internal string
variable that it uses to store the string form of itself. There are many classes that we use that we would normally
never include a string variable in and my associates feel
strongly that to include a string variable in every single
class, just so that the toString() method can return a
string by reference, would be wasteful.

Then there is the option of declaring a string variable in
the base class where the virtual toString() method is
initially declared. This variable would always be available
specifically for use by the toString() method. Again my
associates feel like this would be wasteful as in the
previous case. Plus the toString() method is probably not
always used every time an object is instantiated and so
you end up with the overhead of instantiating a string in
the base class all the time even though you might not
always use the string.

To complicate things further, we actually have three
different virtual toString() methods that we declare in our
base class that all descendent objects must implement. This
is because we've been able to clearly identify three
different context's within which to produce the string form
of any object in the system. In many cases, the resultant
string in these three context's would be different. So with
the previous thoughts in mind, we would probably need to
dedicate three string variables for every object in the
system instead of only one, resulting in even more overhead
in the system and for a purpose that may not get used all
that much.

I should mention the context of all of this; we are doing
development of an intranet application which simply
speaking wraps database data in HTML on the fly and
sends it back to the user's browser. In many cases, these
strings that are being created are actually HTML code.
A call to strlen() on one of these strings could return
a length of hundreds or thousands of bytes!!

The solution we've chosen at this time is to return strings
by-value from the toString() method's. I don't like this
because of the innefficiencies of returning objects
by-value on the stack. But returning strings by-value does
solve all of these problems.

What I would like is to hear from those of you that have
wrestled with these issues and how you have solved them.

I have also thought about building some kind of a global,
reference-counted, auto-garbage-collected list of strings,
that the toString() methods all use. Whenever a toString()
is called, it instantiates a new string and places it in
this list, then it can return a reference to the string in
the list instead of returning the string by value. This
approach would work but might be somewhat complex to implement.

If any of you have any thoughts on this stuff, please let
me know what you think!!

Thanks Much!!!

:^)
0
Comment
Question by:jazzman052397
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 4

Accepted Solution

by:
md041797 earned 200 total points
ID: 1163657
It sounds as though you want to return the same string for each instance of the class.  If this is true, then I would code it like this:

class Whatever : public AnObject {

...

virtual const char * ToString () {return "Whatever";}

....

 };


Then to use say :

Whatever x();
string name (x.ToString());

This way, the only storage used is static data and the amount is limited to one string per class type.

If the string contents are variable per each instance then I would not hesitate to contruct a new string whenever this member is called.  The speed trade-off should be negligable in exchange for efficient memory usage, but of course it depends upon the problem domain.  Note that in C++ if you return an object using a constructor, there is no copying involved:

string ToString () {
 return string (however you want to construct);
 }

 vs

string ToString {
 string s (make it here);
 return s;
 }

in the second instance, the copy constructor is called, but in the first, the object is contructed once on the stack. However, most implementations of string use reference counting, and copy-on-write, so copy constuctors and operator = are more efficient than you would expect.


0
 

Author Comment

by:jazzman052397
ID: 1163658
Edited text of question
0
 

Author Comment

by:jazzman052397
ID: 1163659
MD's answer was a good one, but while reading his/her response, I
realized that I forgot to state the context of our development
which is intranet development, producing HTML on the fly in
a CGI program. The strings we use are many times hundreds and
even thousands of bytes long. So with that in mind I am curious
to see if MD would change his/her response at all.

MD's one statement regarding returning a string via a
constructor results in the copy constructor NOT being called
in a return-by-value situation, was something I was not aware
of and will be helpful to us!!

0
 
LVL 4

Expert Comment

by:md041797
ID: 1163660
Then the best method is to create a new string with each invocation of ToString();  As I stated before, most implementaions of string use a handle / class idiom where the actual storage is in a hidden object and multiple instances of string are actually just pointers to the hidden object, so that:

string s1 ("a long long string");
string s2 = s1;
string s3 (s1);

s1, s2, s3 all point to a hidden stringRef object that holds a reference count of three and "a long long string"

so that passing by value only involves resetting a pointer and incrementing the ref count, not allocate & copy as you would expect.

This means that the performance hit would be low when passing bby value.


0
 
LVL 4

Expert Comment

by:md041797
ID: 1163661
BTW a good reference for these kinds of idioms is _Advanced C++ Programming Styles and Idioms_ by James Coplien of Bell Labs.  Addison-Wesley 0-201-54855-0
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question