Singelton Pattern Unsave?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marcin Vorbrodt

    Singelton Pattern Unsave?

    Hello dear fellows C++ coders!
    I saw a discussion here before about static memebr functions and doing
    singelton pattern. It was sugested that method like this was unsave (example
    from my code):

    class Vector {
    Vector(float, float, float);
    ...
    static const Vector UNIT_X(void);
    };

    const Vector Vector::UNIT_X( void) {
    static const Vector unitX(1.0, 0.0, 0.0);
    return unitX;
    }

    Instead, it was recomende by someone to do this:

    const Vector Vector::UNIT_X( void) {
    static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
    return *unitX;
    }

    Could some please explain exactly why that might be? Also, if the static
    object is const, could I return by reference to the static object, like
    this:

    const Vector& Vector::UNIT_X( void) {
    static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
    return *unitX;
    }

    This would be faster (no need for a temporary), but would it be safe to
    return a reference? Or should I stick with returning a new copy each time?

    Thanks a bunch!

    Marcin


  • Victor Bazarov

    #2
    Re: Singelton Pattern Unsave?

    "Marcin Vorbrodt" <mvorbro@eos.nc su.edu> wrote...[color=blue]
    > I saw a discussion here before about static memebr functions and doing
    > singelton pattern. It was sugested that method like this was unsave[/color]
    (example[color=blue]
    > from my code):[/color]

    Who suggested that? If it were suggested here, why not continue in
    the same thread?
    [color=blue]
    >
    > class Vector {
    > Vector(float, float, float);
    > ...
    > static const Vector UNIT_X(void);[/color]

    'void' instead of the argument list is C. In C++ you don't need it.
    Just write '()'. Much easier to read.
    [color=blue]
    > };
    >
    > const Vector Vector::UNIT_X( void) {
    > static const Vector unitX(1.0, 0.0, 0.0);
    > return unitX;[/color]

    This is nonsense. Why do you return by value? Much more efficient
    would be to return by reference. Besides, if you return by value,
    there is no singleton per se. You always create another instance of
    Vector (by copying the static one).
    [color=blue]
    > }
    >
    > Instead, it was recomende by someone to do this:
    >
    > const Vector Vector::UNIT_X( void) {
    > static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
    > return *unitX;[/color]

    By whom? Again, try not to start unnecessary threads, keep the
    discussion going. Ask questions right there and then.
    [color=blue]
    > }
    >
    > Could some please explain exactly why that might be?[/color]

    Why what might be? Unsafe? Bullshit. There is no safety involved
    here. Take a look:

    Vector unit_X = Vector::UNIT_X( );

    No matter what you return from UNIT_X() member function, I can change
    the 'unit_X' object and you cannot do anything about it. I can shoot
    myself in the foot if I want to, there is nothing you can do to stop me.

    If there is any other safety that you can think of, please elaborate.
    [color=blue]
    > Also, if the static
    > object is const, could I return by reference to the static object, like
    > this:[/color]

    You not only _could_, you _should_.
    [color=blue]
    >
    > const Vector& Vector::UNIT_X( void) {
    > static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
    > return *unitX;
    > }
    >
    > This would be faster (no need for a temporary), but would it be safe to
    > return a reference? Or should I stick with returning a new copy each time?[/color]

    Where's that concern of safety coming from? What could be _unsafe_
    about returning a reference to a const object? BTW, creating a pointer
    and dereferencing it is (a) dangerous because you don't check for any
    errors (what if there isn't enough memory to allocate a Vector?) and
    (b) sloppy because you never free the memory you allocate.

    Victor


    Comment

    • Marcin Vorbrodt

      #3
      Re: Singelton Pattern Unsave?

      "Victor Bazarov" <v.Abazarov@att Abi.com> wrote in message
      news:Nga9b.3459 10$Oz4.130557@r wcrnsc54...[color=blue]
      > "Marcin Vorbrodt" <mvorbro@eos.nc su.edu> wrote...[color=green]
      > > I saw a discussion here before about static memebr functions and doing
      > > singelton pattern. It was sugested that method like this was unsave[/color]
      > (example[color=green]
      > > from my code):[/color]
      >
      > Who suggested that? If it were suggested here, why not continue in
      > the same thread?
      >[/color]


      I dont think that thread is still on my news server.

      [color=blue][color=green]
      > >
      > > class Vector {
      > > Vector(float, float, float);
      > > ...
      > > static const Vector UNIT_X(void);[/color]
      >
      > 'void' instead of the argument list is C. In C++ you don't need it.
      > Just write '()'. Much easier to read.
      >[/color]


      Will keep that in mind.

      [color=blue][color=green]
      > > };
      > >
      > > const Vector Vector::UNIT_X( void) {
      > > static const Vector unitX(1.0, 0.0, 0.0);
      > > return unitX;[/color]
      >
      > This is nonsense. Why do you return by value? Much more efficient
      > would be to return by reference. Besides, if you return by value,
      > there is no singleton per se. You always create another instance of
      > Vector (by copying the static one).
      >[color=green]
      > > }
      > >
      > > Instead, it was recomende by someone to do this:
      > >
      > > const Vector Vector::UNIT_X( void) {
      > > static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
      > > return *unitX;[/color]
      >
      > By whom? Again, try not to start unnecessary threads, keep the
      > discussion going. Ask questions right there and then.
      >[color=green]
      > > }
      > >
      > > Could some please explain exactly why that might be?[/color]
      >
      > Why what might be? Unsafe? Bullshit. There is no safety involved
      > here. Take a look:
      >[/color]


      Yes, but i am returning a reference to memeory (read only memory, but
      still).
      Is there a possibility some would cast away the constness and overwrite the
      value? Or would that result in a runtime error/core dump?

      [color=blue]
      > Vector unit_X = Vector::UNIT_X( );
      >
      > No matter what you return from UNIT_X() member function, I can change
      > the 'unit_X' object and you cannot do anything about it. I can shoot
      > myself in the foot if I want to, there is nothing you can do to stop me.
      >
      > If there is any other safety that you can think of, please elaborate.
      >[color=green]
      > > Also, if the static
      > > object is const, could I return by reference to the static object, like
      > > this:[/color]
      >
      > You not only _could_, you _should_.
      >[color=green]
      > >
      > > const Vector& Vector::UNIT_X( void) {
      > > static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
      > > return *unitX;
      > > }
      > >
      > > This would be faster (no need for a temporary), but would it be safe to
      > > return a reference? Or should I stick with returning a new copy each[/color][/color]
      time?[color=blue]
      >
      > Where's that concern of safety coming from? What could be _unsafe_
      > about returning a reference to a const object? BTW, creating a pointer
      > and dereferencing it is (a) dangerous because you don't check for any
      > errors (what if there isn't enough memory to allocate a Vector?) and
      > (b) sloppy because you never free the memory you allocate.
      >[/color]


      Safety... one I just mentioned... returning effectively a memory address,
      although i dont know if it would/could be modified.

      Two... those are static objects. Static objects on a stack get destroyed
      before the program exits right? The order of destruction (just like the
      order of creation of static objects between compilation units) is unknown.
      What IF (really HUGE IF), at destruction of some static object, that object
      depends on some other static object... which has allready been destroyed.
      Then shit hits the fan, doesn't it? Say a destructor for some other class
      does something along those lines...

      ~OtherClass() {
      .... ble ble ble...
      .... Vector::UNIT_X( );
      }

      and this code happend during destruction of OtherClass static variable.
      Well, the static inside UNIT_X could have been destroyed allready, right?

      Putting it on the heap assures it will exist past the point of program
      termination... OS will release the memory.

      [color=blue]
      > Victor[/color]


      Martin

      [color=blue]
      >
      >[/color]


      Comment

      • Marcelo Pinto

        #4
        Re: Singelton Pattern Unsave?

        "Victor Bazarov" <v.Abazarov@att Abi.com> wrote in message news:<Nga9b.345 910$Oz4.130557@ rwcrnsc54>...
        [snip][color=blue]
        >
        > BTW, creating a pointer
        > and dereferencing it is (a) dangerous because you don't check for any
        > errors (what if there isn't enough memory to allocate a Vector?) and
        > (b) sloppy because you never free the memory you allocate.
        >
        > Victor[/color]

        I believe he doesn't have to check for errors because new throws an
        exception if it cannot allocate memory.

        Regards,

        Marcelo Pinto

        Comment

        • Marcelo Pinto

          #5
          Re: Singelton Pattern Unsave?

          "Marcin Vorbrodt" <mvorbro@eos.nc su.edu> wrote in message news:<bk2qll$j5 r$1@uni00nw.uni ty.ncsu.edu>...[color=blue]
          > Hello dear fellows C++ coders!
          > I saw a discussion here before about static memebr functions and doing
          > singelton pattern. It was sugested that method like this was unsave (example
          > from my code):
          >[/color]

          As Victor pointed out, you should have posted a follow up to that
          thread
          [color=blue]
          > class Vector {
          > Vector(float, float, float);
          > ...
          > static const Vector UNIT_X(void);
          > };
          >
          > const Vector Vector::UNIT_X( void) {
          > static const Vector unitX(1.0, 0.0, 0.0);
          > return unitX;
          > }
          >[/color]

          As I see it, your problem is not quite about singleton. IMO, what you
          are trying is to keep a "constant" avaiable to all the users of your
          class (1,0,0). Probably you will want (0, 1, 0) and (0, 0, 1).
          [color=blue]
          > Instead, it was recomende by someone to do this:
          >
          > const Vector Vector::UNIT_X( void) {
          > static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
          > return *unitX;
          > }
          >[/color]

          I believe that this recommendation came from the book of GoF which
          uses this dialect to create singletons.
          [color=blue]
          > Could some please explain exactly why that might be? Also, if the static
          > object is const, could I return by reference to the static object, like
          > this:
          >
          > const Vector& Vector::UNIT_X( void) {
          > static const Vector *unitX = new Vector(1.0, 0.0, 0.0);
          > return *unitX;
          > }
          >[/color]

          You could mix the two solutions (use return by reference of a static
          local object)

          const Vector & Vector::UNIT_X( void) {
          static const Vector unitX(1.0, 0.0, 0.0);
          return unitX;
          }
          [color=blue]
          > This would be faster (no need for a temporary), but would it be safe to
          > return a reference? Or should I stick with returning a new copy each time?
          >
          > Thanks a bunch!
          >
          > Marcin[/color]

          My incomplete solution to your problem would be:

          //Vector.h
          class Vector
          {
          public:
          Vector(double x, double y, double z):_x(x), _y(y), _z(z) {}
          double & X() { return _x; }
          double & Y() { return _y; }
          double & Z() { return _z; }
          const double & X() const { return _x; }
          const double & Y() const { return _y; }
          const double & Z() const { return _z; }

          static const Vector & Unit_X();
          private:
          double _x, _y, _z;
          };

          //Vector.cpp
          const Vector & Vector::Unit_X( )
          {
          static const Vector UX(1.0, 0.0, 0.0);
          return UX;
          }

          Best Regards,

          Marcelo Pinto

          Comment

          • Victor Bazarov

            #6
            Re: Singelton Pattern Unsave?

            "Marcin Vorbrodt" <mvorbro@eos.nc su.edu> wrote...[color=blue]
            > [...]
            > Safety... one I just mentioned... returning effectively a memory address,
            > although i dont know if it would/could be modified.[/color]

            As I said before, if I want to shoot myself in the foot, you can't
            stop me. Returning a reference to a const vector is efficient, it
            has some protection built in, and it's the best you can do.
            [color=blue]
            > Two... those are static objects. Static objects on a stack get destroyed
            > before the program exits right? The order of destruction (just like the
            > order of creation of static objects between compilation units) is unknown.[/color]

            The order of destruction is the reverse of the order of creation.
            [color=blue]
            > What IF (really HUGE IF), at destruction of some static object, that[/color]
            object[color=blue]
            > depends on some other static object... which has allready been destroyed.
            > Then shit hits the fan, doesn't it? Say a destructor for some other class
            > does something along those lines...
            >
            > ~OtherClass() {
            > ... ble ble ble...
            > ... Vector::UNIT_X( );
            > }
            >
            > and this code happend during destruction of OtherClass static variable.
            > Well, the static inside UNIT_X could have been destroyed allready, right?[/color]

            Unknown. However, you are right to be concerned. And just like with
            many other things, if this can happen, you may want to protect yourself
            or your user and step away from using a static variable. If returning
            a value is not expensive (and you can only find out by profiling the
            code after the entire program is written), return a value.
            [color=blue]
            >
            > Putting it on the heap assures it will exist past the point of program
            > termination... OS will release the memory.[/color]

            Relying on OS to release the memory is non-portable.

            Victor


            Comment

            • Jack Klein

              #7
              Re: Singelton Pattern Unsave?

              On Mon, 15 Sep 2003 03:23:25 GMT, "Victor Bazarov"
              <v.Abazarov@att Abi.com> wrote in comp.lang.c++:
              [color=blue]
              > "Marcin Vorbrodt" <mvorbro@eos.nc su.edu> wrote...[color=green]
              > > I saw a discussion here before about static memebr functions and doing
              > > singelton pattern. It was sugested that method like this was unsave[/color]
              > (example[color=green]
              > > from my code):[/color]
              >
              > Who suggested that? If it were suggested here, why not continue in
              > the same thread?
              >[color=green]
              > >
              > > class Vector {
              > > Vector(float, float, float);
              > > ...
              > > static const Vector UNIT_X(void);[/color]
              >
              > 'void' instead of the argument list is C. In C++ you don't need it.
              > Just write '()'. Much easier to read.[/color]

              "Much easier to read"?

              My sympathy for your poor eyes.

              --
              Jack Klein
              Home: http://JK-Technology.Com
              FAQs for
              comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
              comp.lang.c++ http://www.parashift.com/c++-faq-lite/
              alt.comp.lang.l earn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

              Comment

              Working...