473,406 Members | 2,956 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,406 software developers and data experts.

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
Jul 19 '05 #1
6 2408
"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> wrote...
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):
Who suggested that? If it were suggested here, why not continue in
the same thread?

class Vector {
Vector(float, float, float);
...
static const Vector UNIT_X(void);
'void' instead of the argument list is C. In C++ you don't need it.
Just write '()'. Much easier to read.
};

const Vector Vector::UNIT_X(void) {
static const Vector unitX(1.0, 0.0, 0.0);
return unitX;
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).
}

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;
By whom? Again, try not to start unnecessary threads, keep the
discussion going. Ask questions right there and then.
}

Could some please explain exactly why that might be?
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.
Also, if the static
object is const, could I return by reference to the static object, like
this:
You not only _could_, you _should_.

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?


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
Jul 19 '05 #2
"Victor Bazarov" <v.********@attAbi.com> wrote in message
news:Nga9b.345910$Oz4.130557@rwcrnsc54...
"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> wrote...
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):


Who suggested that? If it were suggested here, why not continue in
the same thread?

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


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


'void' instead of the argument list is C. In C++ you don't need it.
Just write '()'. Much easier to read.

Will keep that in mind.

};

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


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

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;


By whom? Again, try not to start unnecessary threads, keep the
discussion going. Ask questions right there and then.
}

Could some please explain exactly why that might be?


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

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?

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.
Also, if the static
object is const, could I return by reference to the static object, like
this:
You not only _could_, you _should_.

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

Victor

Martin


Jul 19 '05 #3
"Victor Bazarov" <v.********@attAbi.com> wrote in message news:<Nga9b.345910$Oz4.130557@rwcrnsc54>...
[snip]

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


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

Regards,

Marcelo Pinto
Jul 19 '05 #4
"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> wrote in message news:<bk**********@uni00nw.unity.ncsu.edu>...
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):

As Victor pointed out, you should have posted a follow up to that
thread
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;
}

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).
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;
}

I believe that this recommendation came from the book of GoF which
uses this dialect to create singletons.
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;
}

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;
}
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


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
Jul 19 '05 #5
"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> wrote...
[...]
Safety... one I just mentioned... returning effectively a memory address,
although i dont know if it would/could be modified.
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.
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.
The order of destruction is the reverse of the order of creation.
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?
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.

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


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

Victor
Jul 19 '05 #6
On Mon, 15 Sep 2003 03:23:25 GMT, "Victor Bazarov"
<v.********@attAbi.com> wrote in comp.lang.c++:
"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> wrote...
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):


Who suggested that? If it were suggested here, why not continue in
the same thread?

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


'void' instead of the argument list is C. In C++ you don't need it.
Just write '()'. Much easier to read.


"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.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
Jul 19 '05 #7

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

Similar topics

8
by: gsv2com | last post by:
One of my weaknesses has always been pattern matching. Something I definitely need to study up on and maybe you guys can give me a pointer here. I'm looking to remove all of this code and just...
0
by: Andy Read | last post by:
Hello all, I have the requirement to produce source code that produces an object hierarchy. Example: Root | Folder 1
2
by: CV | last post by:
How can I match 'n' number of neighbouring words of a pattern using regular expressions? For example, suppose I am looking for the pattern "length xyz cm" in some text. where xyz is a number -...
11
by: FluffyCat | last post by:
In Febraury - April of 2002 I put together in Java examples of all 23 of the classic "Gang Of Four" design patterns for my website. Partly I wanted to get a better understanding of those patterns....
1
by: Sea Sharper | last post by:
Hi, C#, from a FileSystemWatcher I would like to catch all files with a *.* filter but then inside the event handler compare against a list of wildcards (eg '*.abc;*.def') Is there anywhere...
34
by: Steven Nagy | last post by:
So I was needing some extra power from my enums and implemented the typesafe enum pattern. And it got me to thinking... why should I EVER use standard enums? There's now a nice little code...
11
by: td0g03 | last post by:
Hello, I just have a few questions. The first one be how would you print a pattern. I could use the if else, but I remember my teacher talking about something like for(i=1;i<=size;i) ...
1
by: halekio | last post by:
Hi all, Please bear with me as I've only started programming in C# 2 weeks ago and this is my first contact with OOP. I ran into a situation where I needed to catch an event in an object that...
3
by: Peter | last post by:
Hi I can create types from dynamic loaaded assemblies (Assembly.Load) with Assembly.GetTyp( <typename) - OK I need a reference to the assembly (just Type.GetType() do not work ) now my...
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.