Questing regarding returning of new objects

  • Thread starter thorsten.schilling
  • Start date
T

thorsten.schilling

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::eek:perator+(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::eek:perator+(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
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

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::eek:perator+(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::eek:perator+(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.
 
V

vswathisai

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.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

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.
 
K

Kai-Uwe Bux

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::eek:perator+(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::eek:perator+(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
 
J

James Kanze

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::eek:perator+(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.
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).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top