Questing regarding returning of new objects

Discussion in 'C++' started by thorsten.schilling@gmail.com, Sep 9, 2007.

  1. Guest

    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
     
    , Sep 9, 2007
    #1
    1. Advertising

  2. On 2007-09-09 12:58, 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::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.

    --
    Erik Wikström
     
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, Sep 9, 2007
    #2
    1. Advertising

  3. Guest

    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, 2007
    #3
  4. On 2007-09-09 14:58, 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
     
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, Sep 9, 2007
    #4
  5. Guest

    , Sep 9, 2007
    #5
  6. Kai-Uwe Bux Guest

    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::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
     
    Kai-Uwe Bux, Sep 9, 2007
    #6
  7. James Kanze Guest

    On Sep 9, 1:23 pm, Erik Wikström <> wrote:
    > On 2007-09-09 12:58, 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::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.

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


    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:
    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
     
    James Kanze, Sep 10, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    410
  2. Replies:
    9
    Views:
    393
    Gavin Deane
    Feb 3, 2006
  3. 7stud
    Replies:
    11
    Views:
    717
    Dennis Lee Bieber
    Mar 20, 2007
  4. zebulon
    Replies:
    8
    Views:
    263
    zebulon
    Sep 3, 2008
  5. Andre Linoge

    Frame questing

    Andre Linoge, Jun 30, 2013, in forum: HTML
    Replies:
    2
    Views:
    330
Loading...

Share This Page