473,386 Members | 1,827 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Questing regarding returning of new objects

Hello everybody,

the question is, what is the "golden way" or the best way, if I have a
memberfunction in a class, which should return a new instance of an
object.
For example some class Foo which holds a lot data and has the
overloaded '+' operator and I want to do something like:

//f1-f3 are all Foo instances
f1 = f2+f3;

Is it in that case better to work with pointers in general like:

Foo* Foo::operator+(Foo& f){
//Do stuff
return new Foo([lot,of,data]);
}

to avoid the copying of the data which is hold by the new object at
the end of the function? Or is there any sensefull way to implement
that with a reference (Foo& Foo::operator+(Foo& f)), since it is more
intuitive?
Just imagine that the class Foo is somekind of Matrixclass with a big
2 dimensional array as member variable. Or is the only way just to
write Foo that it holds only a pointer to that big variable? Sure,
there are numerous solutions, but I would like to know which is the
most common and most elegant by some experienced C++ developers.

Thanks in advance,
Thorsten

Sep 9 '07 #1
6 1490
On 2007-09-09 12:58, th****************@gmail.com wrote:
Hello everybody,

the question is, what is the "golden way" or the best way, if I have a
memberfunction in a class, which should return a new instance of an
object.
For example some class Foo which holds a lot data and has the
overloaded '+' operator and I want to do something like:

//f1-f3 are all Foo instances
f1 = f2+f3;

Is it in that case better to work with pointers in general like:

Foo* Foo::operator+(Foo& f){
//Do stuff
return new Foo([lot,of,data]);
}
No, the + operator should return a new object to keep the semantics sane.
to avoid the copying of the data which is hold by the new object at
the end of the function? Or is there any sensefull way to implement
that with a reference (Foo& Foo::operator+(Foo& f)), since it is more
intuitive?
Just imagine that the class Foo is somekind of Matrixclass with a big
2 dimensional array as member variable. Or is the only way just to
write Foo that it holds only a pointer to that big variable? Sure,
there are numerous solutions, but I would like to know which is the
most common and most elegant by some experienced C++ developers.
There are two ways to solve this, the best but hardest to implement is
to use expression templates, unless you are writing a library that will
be used in many different applications this is probably too much work.

The other solution is to not use the + operator and instead use the +=
operator:

Foo f1(f2);
f1 += f3;

There are other solutions but they don't use the same syntax, such as
making a constructor that takes two Foo objects and an operator.

--
Erik Wikström
Sep 9 '07 #2
hi,

what's my query is what's the full neccessity for operator
overloading.Why we are adopting this concept.there is often lies a
complexity working with this concept.Can anyone explain what are all
the easy ways to getting the idea about Runtime POLYMORPHISM.

Sep 9 '07 #3
On 2007-09-09 14:58, vs********@gmail.com wrote:
hi,

what's my query is what's the full neccessity for operator
overloading.Why we are adopting this concept.there is often lies a
complexity working with this concept.
There is no necessity in operator overloading, but by using it we can
simplify the *usage* of the types we design. And just as you say it does
add a little extra complexity when writing the code for the type, but
generally no more than using normal functions would. But the important
thing to remember is that is can greatly simplify the usage of classes,
just look at std::complex. You can use them more or less just like a
normal arithmetic type when you write expressions. Lets take a look at
what the code would look like if you do not have operators for the
following expression:

a = b + c * (d - e / f) * g;

Would be something like:

a = b.add(c.multiply(d.minus(e.devide(f))).multiply(g) );

or

a = add(b, multiply(multiply(c, minus(d, divide(e,f)) , g)));

I am not sure I got the second one correct, might have misplaced a
parenthesis, or perhaps even a whole sub-expression. Both of the
expressions that don't use operators take more to write, are harder to
tell what they do, and are harder to write.
Can anyone explain what are all the easy ways to getting the idea
about Runtime POLYMORPHISM.
You should start a new thread for this question, but performing a search
on google might be a better idea, or search the group archives.

--
Erik Wikström
Sep 9 '07 #4
you return the reference to "this", there is no performance penalty
then, as a reference as same as a pointer

MyClass & MyClass::operator+=(const MyClass &rhs)
{
... // Do the compound assignment work.

return *this;
}

see some details here:
http://www.cs.caltech.edu/courses/cs...e/cpp-ops.html

Sep 9 '07 #5
th****************@gmail.com wrote:
the question is, what is the "golden way" or the best way, if I have a
memberfunction in a class, which should return a new instance of an
object.
For example some class Foo which holds a lot data and has the
overloaded '+' operator and I want to do something like:

//f1-f3 are all Foo instances
f1 = f2+f3;

Is it in that case better to work with pointers in general like:

Foo* Foo::operator+(Foo& f){
//Do stuff
return new Foo([lot,of,data]);
}

to avoid the copying of the data which is hold by the new object at
the end of the function? Or is there any sensefull way to implement
that with a reference (Foo& Foo::operator+(Foo& f)), since it is more
intuitive?
Just imagine that the class Foo is somekind of Matrixclass with a big
2 dimensional array as member variable. Or is the only way just to
write Foo that it holds only a pointer to that big variable? Sure,
there are numerous solutions, but I would like to know which is the
most common and most elegant by some experienced C++ developers.
You are concerned about the costs of copying a temporary object. There are
several things that help here:

a) A compiler can implement return value optimization. In the case of a
function like

Foo operator+ ( Foo const & lhs, Foo const & rhs ) {
Foo result ( something );
...
return ( result );
}

the standard permits that the result value be constructed in a place
convenient for the caller of operator+ so that copying the result is
avoided. Many compilers implement this. In this case, your question
interpreted in the narrowest scope becomes pointless. But a more general
concern about the copy costs of big objects remains.
b) The class can internally employ reference counting and make copying
cheap. I.e., you can implement Foo like so (untested, will be buggy):

class Foo {

tr1::shared_ptr< FooData the_data;

void ensure_unique ( void ) {
if ( ! the_data.unique() ) {
shared_ptr< FooData new_data ( new FooData ( *the_data ) );
the_data.swap( new_data );
}
}

public:

...

void some_const_method ( some_type some_par ) const {
the_data->some_const_method( some_par );
}

void some_non_const_method ( some_type some_par ) {
ensure_unique();
the_data->some_non_const_method( some_par );
}

};

Now, copying is cheap, but you add a little overhead just about everywhere
else. Also note that non-const members may have to create their private
copy of the data anyhow.
c) Expression templates can be used to trade the creation of costly
temporaries for creation of cheap temporaries. This technique is employed
in some publicly available matrix classes. Expression templates allow you
to reduce the number of costly objects created by postponing the actual
creation of costly objects to the very last moment (at which point some
temporaries have been bypassed). You will find plenty of information about
this in the archives.
BTW: if your Foo really is a matrix class, I strongly suggest using one of
the classes around. It is rather tricky to get a matrix class Right(tm).
Best

Kai-Uwe Bux
Sep 9 '07 #6
On Sep 9, 1:23 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-09-09 12:58, thorsten.schill...@gmail.com wrote:
the question is, what is the "golden way" or the best way,
if I have a memberfunction in a class, which should return a
new instance of an object. For example some class Foo which
holds a lot data and has the overloaded '+' operator and I
want to do something like:
//f1-f3 are all Foo instances
f1 = f2+f3;
Is it in that case better to work with pointers in general like:
Foo* Foo::operator+(Foo& f){
//Do stuff
return new Foo([lot,of,data]);
}
No, the + operator should return a new object to keep the
semantics sane.
100% agreed. The semantics of the final program must always be
as if operator+ returned a new object. And not a new'ed object;
it's almost impossible to use an operator+ which returns a
new'ed object without leaking memory.

Of course, the the returned object doesn't have to be of type
Foo. A frequent solution is to return a proxy of some sort.
to avoid the copying of the data which is hold by the new
object at the end of the function? Or is there any sensefull
way to implement that with a reference (Foo&
Foo::operator+(Foo& f)), since it is more intuitive? Just
imagine that the class Foo is somekind of Matrixclass with a
big 2 dimensional array as member variable. Or is the only
way just to write Foo that it holds only a pointer to that
big variable? Sure, there are numerous solutions, but I
would like to know which is the most common and most elegant
by some experienced C++ developers.
There are two ways to solve this, the best but hardest to
implement is to use expression templates, unless you are
writing a library that will be used in many different
applications this is probably too much work.
It's actually not that much work, total. It's a lot of extra
code, but it's grunt code, which doesn't require much thought,
once the design has been decided on. (I've not tried, since I
haven't needed such in my applications, but I'll bet you could
write a simple script to generate it: you specify the base type
and the desired operators, and the script generates the rest.)

Note too that you don't really need templates for this;
inheritance works just as well. The technique was being used
long before C++ compilers supported templates. (It's a curious
case of inheritance, since the virtual functions are all inline,
and all of the objects of the derived class are normally
temporaries, generated by the compiler on the stack, and whose
dynamic type is known to the compiler, so it doesn't have to
generate the usual code for a virtual function call.)
The other solution is to not use the + operator and instead
use the += operator:
Foo f1(f2);
f1 += f3;
That puts the onus on the user, and is a real pain for more
complicated expressions (which require explicit temporaries).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 10 '07 #7

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

Similar topics

6
by: akash shetty | last post by:
hi, im developing a code which requires searching a large database(bioological) for certain patterns.the size of the file is 3.5GB . the search pattern is a ten letter string.the database...
18
by: cppaddict | last post by:
Hi, Is it considered bad form to have the subscript operator return a const reference variable? If not, what is the proper way to do it? My question was prompted by the code below, my...
12
by: Olumide | last post by:
I'm studying Nigel Chapman's Late Night Guide to C++ which I think is an absolutely fantastic book; however on page 175 (topic: operator overlaoding), there the following code snippet: inline...
8
by: Derek | last post by:
Some authors advocate returning const objects: const Point operator+(const Point&, const Point&); ^^^^^ Returning a const object prevents some bad code from compiling: Point a, b, c; (a +...
8
by: gg | last post by:
I am confused regarding what the line in the following function does. It seems to work ok. It seems to be creating a new T object using the pointer to an existing T object. But which function is it...
1
by: trialproduct2004 | last post by:
Hi all, I am having slight confusion regarding memory management in .net. Say suppose i have two application one is in C# and other is in MFC(VC++). Both of this application are using lots...
8
by: Myron Marston | last post by:
For a WebService I am developing, I return a DataSet that contains a table listing Field Names and Field Values. The FieldValue column is given the type object becuase it can potentially contain...
2
by: dejavue82 | last post by:
Dear ASP.net programmers, I was wondering about the following: 1) Do hosts automatically support all of the .NET framework? (ex. System.Image) 2) If one rents a dedicated server, does one...
7
by: Thomas Lenz | last post by:
Please consider the following code snippet: string myfunction() { ostringstream oss; oss << "junk"; // do something more with oss; I can't make it const... return oss.str(); } Is the...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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...

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.