-
A question regarding singleton
Here is a simple implementation of singleton,
Code:
class A
{
private:
A(int x) : _x(x)
{
}
int _x;
friend A& createA(int x)
{
static A a(x);
return a;
}
};
int main()
{
A a1 = createA(1);
A a2 = createA(2);
return 0;
}
By debugging, I found that a1._x = 1 and a2._x = 1. It looks like only one object is created. But I wonder why returning static object a can guarantee only one object is created.
-
Re: A question regarding singleton
Aside from the fact that your creator function needs to be static instead of friend...
Quote:
Originally Posted by
LarryChen
By debugging, I found that a1._x = 1 and a2._x = 1. It looks like only one object is created.
Creating only one object is the intention behind a singleton. ;) Your creator function instantiates the static variable only once when it is first called, and subsequentially just returns a reference to that very instance.
Quote:
But I wonder why returning static object a can guarantee only one object is created.
Just returning a reference to a static doesn't do that. Your objects a1 and a2 are actually copies (created by the compiler-generated default copy constructor) of the "singleton" object, thus breaking the singleton concept. You can simply check that by assigning something to the _x member of one of the objects in main() (after making that member public).
You need not only to return a reference, you also need to initialize references from it instead of making copies. To enforce that you need to declare a private copy constructor and assignment operator which disables copying and assignment.
BTW, an alternative to returning a reference in the singleton pattern is to return a pointer to the single reference. But that doesn't change anything about the principle.
-
Re: A question regarding singleton
Quote:
But I wonder why returning static object a can guarantee only one object is created.
What you have there isn't really a singleton... it's something more like a factory. Only one A exists within the createA() function (thanks to it being static), but you have more than one A in your program (three of them, in fact). You're just forced to create them by calling createA().
-
Re: A question regarding singleton
[QUOTE=Eri523;2011149]Aside from the fact that your creator function needs to be static instead of friend...
Why does the creator function need to be static? Take a look at the following implementation,
Code:
class A
{
private:
A(int x) : _x(x)
{
}
A(const A&){}
operator=(const A&){}
int _x;
friend A& createA(int x)
{
static A a(x);
return a;
}
};
Is there anything wrong? Thanks.
-
Re: A question regarding singleton
Quote:
Originally Posted by LarryChen
Why does the creator function need to be static?
It doesn't need to be a static member function, but with such factory functions it is more conventional to write:
Code:
A a1 = A.create(1);
rather than
unless createA can be a non-member non-friend.
-
Re: A question regarding singleton
Quote:
Originally Posted by
LarryChen
Take a look at the following implementation,
[...]
Is there anything wrong? Thanks.
Did you actually try to compile that? ;)
Aside from that, I see absolutely no point in making a member function a friend of its own class.
-
Re: A question regarding singleton
Quote:
Originally Posted by Eri523
I see absolutely no point in making a member function a friend of its own class.
I do not think it is possible to make a member function a friend of its own class.
-
Re: A question regarding singleton
Quote:
Originally Posted by
laserlight
It doesn't need to be a static member function [...]
To my understanding a singleton instance accessor that is a non-static member of the singleton is completely paradox. Ths instance accessor can be a non-static class member, but then of another class, at least as I understand the description at http://en.wikipedia.org/wiki/Singlet...method_pattern.
I think it's also possible to make the instance accessor a free friend function of the singleton, but then it would still implicitly be static.
Quote:
Originally Posted by
laserlight
I do not think it is possible to make a member function a friend of its own class.
To my surprise, the following actually does compile under VC++ 2010:
Code:
#include <iostream>
using namespace std;
class B
{
public:
B() : m_x(23)
{}
private:
friend int getx(const B &b_)
{
return b_.m_x;
}
int m_x;
};
int main()
{
B b;
cout << getx(b) << endl;
return 0;
}
But note that in this scenario getx() actually is a disguised free function.
-
Re: A question regarding singleton
Is it that disguised? After all we all expect a friend function to be a free function so isn't this more about where it's implemented?
I think laserligths statement still is true since it should be impossible to implement it as B::getx
-
Re: A question regarding singleton
Quote:
Originally Posted by
S_M_A
I think laserligths statement still is true since it should be impossible to implement it as B::getx
I agree. That code is just my attempt to find out the OP's (potential) intention behind the (non-compiling) code from post #1 and how it might be turned into something that actually does compile, mostly regardless of what would then be the result of that compilation, or better, trying to find out what that result then would be. :o
-
Re: A question regarding singleton
And that's absolutely nothing to be embarressed for and that wasn't my intention either. I was just happy that I had knowledge enough to be part of the thread. :)
-
Re: A question regarding singleton
Update: The Comeau compiler accepted the code from post #8 without any complaints as well.
-
Re: A question regarding singleton
Quote:
Originally Posted by Eri523
To my understanding a singleton instance accessor that is a non-static member of the singleton is completely paradox.
A non-member function is also not a static member function ;)
In fact, that is how I understood the point that LarryChen was making. It seemed to me that LarryChen correctly identified the friend function createA as a non-member function, despite it being defined within the definition of a class.
Quote:
Originally Posted by Eri523
I think it's also possible to make the instance accessor a free friend function of the singleton, but then it would still implicitly be static.
No, it wouldn't implicitly be static, because the static specifier as applied to free functions has a different, though related, meaning.
-
Re: A question regarding singleton
Ah, I'm gradually getting it... I obviously misinterpreted your sentence:
Quote:
Originally Posted by
laserlight
It doesn't need to be a static member function [...].
You actually meant it doesn't need to be a member at all (which of course is absolutely right) and I interpreted that as "it needs to be a member, just not static". :o This misunderstanding probably got some extra promotion from the fact that I myself actually prefer static member instance accessors because I find they make it more obvious what they're intended for.
Quote:
Originally Posted by
laserlight
A non-member function is also not a static member function ;)
[...]
No, it wouldn't implicitly be static, because the static specifier as applied to free functions has a different, though related, meaning.
Looks like another communication problem, this time of type "terminology clash"... And it's clearly my own fault. With respect to the topic of this thread, I more or less intentionally misused the word static. I used it with the meaning "not object-bound" but of course it has another meaning for free functions. When I wrote it I was assuming it was perfectly clear and understandable what I meant, but obviously I was sooo wrong... :( :blush:
-
Re: A question regarding singleton
Quote:
Originally Posted by
laserlight
It seemed to me that LarryChen correctly identified the friend function createA as a non-member function, despite it being defined within the definition of a class.
I'm not saying you're wrong, and my intention is entirely to learn something, but, from an OO design point of view: how can a function the enclosing context of which is a class not be a member function of that class?
Is this something C++ specific? (My weapon of choice is C#, so - maybe I'm missing something...) Or maybe the words "member function" have a slightly different meaning for us? :confused:
-
Re: A question regarding singleton
I think (I can't seem to find a good reference online) that functions that are friends cannot be member functions of another class. Therefore, if the compiler sees a friend function enclosed in a class definition, it can assume that the function is indeed free, so there is no error.
Classes can be friends of other classes, which would allow the member functions of one class access to data members of the other.
Viggy
-
Re: A question regarding singleton
Quote:
Originally Posted by
MrViggy
I think (I can't seem to find a good reference online) that functions that are friends cannot be member functions of another class. Therefore, if the compiler sees a friend function enclosed in a class definition, it can assume that the function is indeed free, so there is no error.
Classes can be friends of other classes, which would allow the member functions of one class access to data members of the other.
Viggy
http://www.cplusplus.com/doc/tutorial/inheritance/
Yep, this is be definition.
Viggy
-
Re: A question regarding singleton
Aah, I think I see. Well, at least in part. So, a friend function is a free function no matter what. The language design choice to make it possible to declare it as such and to define it at the same time feels a bit... strange to me. Doesn't this introduce some confusion (assuming that you don't know everything there is to know about friend functions)? Unless there's some scenario where this would be significantly beneficial?
So, basically, the enclosing class-level scope is non-existent to such a function? BTW, do any access modifiers have any effect? If it's not a member - they shouldn't. Which makes it all the more misleading when you list the function under one... I don't know. The whole practice feels wrong to me.
-
Re: A question regarding singleton
Quote:
Originally Posted by
TheGreatCthulhu
Doesn't this introduce some confusion (assuming that you don't know everything there is to know about friend functions)?
Oh yes, it definitely does, at least for me. If it didn't, I probably wouldn't have posted in this thread at all.
Quote:
Unless there's some scenario where this would be significantly beneficial?
I tried to construct such a scenario (involving multiple classes derived from a common base class to provoke multiple definition errors) but to no avail: I always found a way to define the friend function outside of the class body.
-
Re: A question regarding singleton
Now is it safe to say singleton creator function could be either friend function or static function of a singleton class? So we have two choices.
-
Re: A question regarding singleton
Quote:
Originally Posted by MrViggy
I think (I can't seem to find a good reference online) that functions that are friends cannot be member functions of another class. Therefore, if the compiler sees a friend function enclosed in a class definition, it can assume that the function is indeed free, so there is no error.
I have not checked the standard, but g++ 4.4.5 and the Comeau online compiler happily compile:
Code:
class B;
class A
{
public:
void foo(const B& b) const;
};
class B
{
public:
explicit B(int x) : x_(x) {}
friend void A::foo(const B& b) const;
private:
int x_;
};
#include <iostream>
void A::foo(const B& b) const
{
std::cout << b.x_ << std::endl;
}
int main()
{
A a;
B b(123);
a.foo(b);
}
Besides, while it does not make sense for a member function to be a friend of its own class, it does make sense for it to be a friend of another class, without its class being a friend (i.e., reduced penalty in loss of encapsulation).
Quote:
Originally Posted by LarryChen
Now is it safe to say singleton creator function could be either friend function or static function of a singleton class? So we have two choices.
Yes.
-
Re: A question regarding singleton
Quote:
Originally Posted by
TheGreatCthulhu
Unless there's some scenario where this would be significantly beneficial?
name injection, like the Barton–Nackman trick as a notable example ( this is used in many boost libraries, like boost operators, boost iterators and others ... ). Note that in these scenarios this language feature is not only beneficial but also necessary.
EDIT: @TheGreatCthulhu, ... ignore my post above given that I misinterpreted yours :) ...
-
Re: A question regarding singleton
Quote:
Originally Posted by
LarryChen
Now is it safe to say singleton creator function could be either friend function or static function of a singleton class? So we have two choices.
The Singleton design pattern stipulates that there's global access to one unique object, the rest is implementation detail. What you're attempting is called a Meyer's Singleton but that's just one way to do it.
-
Re: A question regarding singleton
Quote:
Originally Posted by
LarryChen
Now is it safe to say singleton creator function could be either friend function or static function of a singleton class? So we have two choices.
Both approaches will work. In general, however, it's better to use a static method because that's what the design pattern specifies, and so that's what anyone reading your code would expect to see. If you tell someone to get the MyClass singleton but don't show them any code, they're far more likely to figure out "MyClass::getInstance()" than "getMyClassInstance()" as the way to do it.
-
Re: A question regarding singleton
Quote:
Originally Posted by
Lindley
however, it's better to use a static method because that's what the design pattern specifies,
That's wrong.
Design patterns are language independent and no implementations are stipulated.
-
Re: A question regarding singleton
Quote:
Originally Posted by
TheGreatCthulhu
but, from an OO design point of view: how can a function the enclosing context of which is a class not be a member function of that class?
What OO design point of view are you referring to?
-
Re: A question regarding singleton
Quote:
Originally Posted by
laserlight
Code:
//...
friend void A::foo(const B& b) const;
//...
Now that does make sense to me.
Quote:
Originally Posted by
superbonzo
EDIT: @TheGreatCthulhu, ... ignore my post above given that I misinterpreted yours :) ...
Yes - my point was: in what cases would declaring and defining a friend function at the same time within a scope of the class be significantly beneficial or desirable (in a way that would make sacrificing clarity worth it)? What's was the compelling reason for the language to allow it in the first place? Nevertheless, I did found your link informative.
Quote:
Originally Posted by
nuzzle
That's wrong.
Design patterns are language independent and no implementations are stipulated.
Yes - they are implementation independent - but note that they define a certain logical structure. The standard Singleton pattern provides a static function, and this is what people would expect. Logically, a static function is not the same as a free function. However, you are not entirely wrong either: when it comes to the implementation - not all the languages provide the same features; furthermore, with design patterns, nothing's really set in stone - and that's one of the benefits.
But, one advantage of using patterns is that they define a sort of a language, a standard way to talk about common design solutions - a common grounds of sorts, so that those who are familiar with them can easily exchange ideas and information. For this reason, it's (IMO) best to leverage this advantage by implementing a pattern behind an interface most people would expect, especially if your language supports it.
Quote:
Originally Posted by
nuzzle
What OO design point of view are you referring to?
Well, how would you model that (a function defined within a class, which is not a member of that class)?
It's a C++ -specific thing (but not in the sense that there aren't any other languages that have that (there could be), but in the sense that it falls outside the scope of your standard OO paradigm, or at least it's something else in disguise).
-
Re: A question regarding singleton
The word "specifies" in my post may have been poorly chosen, but the general point I was making stands.
-
Re: A question regarding singleton
Quote:
Originally Posted by
TheGreatCthulhu
Yes - my point was: in what cases would declaring and defining a friend function at the same time within a scope of the class be significantly beneficial or desirable (in a way that would make sacrificing clarity worth it)? What's was the compelling reason for the language to allow it in the first place? Nevertheless, I did found your link informative.
ah ... well, then my orignal interpretation of your post was correct; I mean, to my knowledge there's no way of defining those friend non member functions outside of the class template body when they depend on the template parameters. So, this is a scenario where this language feature is indeed necessary.