Singleton : avoid GetIntance()
up vote
-1
down vote
favorite
Everyone knows the singleton pattern (very simple exemple) :
class Singleton
{
private:
static Singleton* instance;
public:
static Singleton* GetInstance() { return instance; }
void Foo() {}
};
And the use :
Singleton::GetInstance()->Foo();
I wonder, why this GetInstance()
is mandatory. I've tried to find a way to eliminate the call to this function, to be able to write for exemple... :
Singleton->Foo();
... using the class name the same way I use a variable, because of the singleton pattern, and others security like deleting the public constructor for exemple, we are sure that we only have a single instance, so why not "using the class as a variable" (quote, unquote, only syntaxic speaking of course !).
Each time, a C++ rule prohibit following exemples :
Singleton->Foo(); // (1)
Singleton()->Foo(); // (2)
Singleton.Foo(); // (3)
Singleton::Foo(); // (4)
Because :
- (1)
static Singleton* operator->() { return instance; }
is impossible, Class Member Access Operator (->) overload can't be static (see C2801), same for (2) with operator () - (3) and (4) operators . and :: can't be overloaded
Only solution here : Macros, but I'm actually using macros, and I want to find an other way and avoiding macros for this...
It's only a syntaxic interrogation, I'm not here to debate about pros and cons of singletons, but I wonder why C++ permit so many things for simplify the use syntax of users classes with overloads, user literals, and we can't eliminate this little function from the pattern.
I don't expect a solution (but if there is one, it would be great), it's just to understand why, to know if there is a explanation, a design reason, a security reason or anything else !
Thanks in advance !
c++ singleton
add a comment |
up vote
-1
down vote
favorite
Everyone knows the singleton pattern (very simple exemple) :
class Singleton
{
private:
static Singleton* instance;
public:
static Singleton* GetInstance() { return instance; }
void Foo() {}
};
And the use :
Singleton::GetInstance()->Foo();
I wonder, why this GetInstance()
is mandatory. I've tried to find a way to eliminate the call to this function, to be able to write for exemple... :
Singleton->Foo();
... using the class name the same way I use a variable, because of the singleton pattern, and others security like deleting the public constructor for exemple, we are sure that we only have a single instance, so why not "using the class as a variable" (quote, unquote, only syntaxic speaking of course !).
Each time, a C++ rule prohibit following exemples :
Singleton->Foo(); // (1)
Singleton()->Foo(); // (2)
Singleton.Foo(); // (3)
Singleton::Foo(); // (4)
Because :
- (1)
static Singleton* operator->() { return instance; }
is impossible, Class Member Access Operator (->) overload can't be static (see C2801), same for (2) with operator () - (3) and (4) operators . and :: can't be overloaded
Only solution here : Macros, but I'm actually using macros, and I want to find an other way and avoiding macros for this...
It's only a syntaxic interrogation, I'm not here to debate about pros and cons of singletons, but I wonder why C++ permit so many things for simplify the use syntax of users classes with overloads, user literals, and we can't eliminate this little function from the pattern.
I don't expect a solution (but if there is one, it would be great), it's just to understand why, to know if there is a explanation, a design reason, a security reason or anything else !
Thanks in advance !
c++ singleton
1
BTW, This method comes strongly recommended: stackoverflow.com/a/1008289/3807729
– Galik
Nov 11 at 0:54
You can hide a singleton with a façade of static class functions, e.g.,static void Foo() { GetInstance()->Foo(); }
, then the callsite would only have to doSingleton::Foo();
which is pretty close to (4).
– Eljay
Nov 11 at 0:59
@Galik, interesting link, thanks. But i will go a little it further : I understand that this method can be important for destruction explained in your link, and in fact, I do not want to remove it from the class, only from the user code. Admit that operator -> can be static I could write :static Singleton* operator->() { return GetInstance(); }
, and useSingleton->Foo();
, the problem is not the existence of the method, but the call to this method in user code !
– Monk
Nov 11 at 1:03
@Eljay It's what I've thinking, but it mean that we always have to change all methods of all singletons class to statics methods or duplicate all publics methods to get a static version calling a non static version of the method... It's why I just speak of syntax, I don't want to change meaning of the existing code !
– Monk
Nov 11 at 1:06
There is a different pattern called the Monostate pattern. Very similar to a Singleton. All the functions are static functions ("class functions"), and all the data is in static variables ("class variables"). Any instances are empty, so usage just acts as a proxy for the class functions and class variables.
– Eljay
Nov 11 at 13:32
add a comment |
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
Everyone knows the singleton pattern (very simple exemple) :
class Singleton
{
private:
static Singleton* instance;
public:
static Singleton* GetInstance() { return instance; }
void Foo() {}
};
And the use :
Singleton::GetInstance()->Foo();
I wonder, why this GetInstance()
is mandatory. I've tried to find a way to eliminate the call to this function, to be able to write for exemple... :
Singleton->Foo();
... using the class name the same way I use a variable, because of the singleton pattern, and others security like deleting the public constructor for exemple, we are sure that we only have a single instance, so why not "using the class as a variable" (quote, unquote, only syntaxic speaking of course !).
Each time, a C++ rule prohibit following exemples :
Singleton->Foo(); // (1)
Singleton()->Foo(); // (2)
Singleton.Foo(); // (3)
Singleton::Foo(); // (4)
Because :
- (1)
static Singleton* operator->() { return instance; }
is impossible, Class Member Access Operator (->) overload can't be static (see C2801), same for (2) with operator () - (3) and (4) operators . and :: can't be overloaded
Only solution here : Macros, but I'm actually using macros, and I want to find an other way and avoiding macros for this...
It's only a syntaxic interrogation, I'm not here to debate about pros and cons of singletons, but I wonder why C++ permit so many things for simplify the use syntax of users classes with overloads, user literals, and we can't eliminate this little function from the pattern.
I don't expect a solution (but if there is one, it would be great), it's just to understand why, to know if there is a explanation, a design reason, a security reason or anything else !
Thanks in advance !
c++ singleton
Everyone knows the singleton pattern (very simple exemple) :
class Singleton
{
private:
static Singleton* instance;
public:
static Singleton* GetInstance() { return instance; }
void Foo() {}
};
And the use :
Singleton::GetInstance()->Foo();
I wonder, why this GetInstance()
is mandatory. I've tried to find a way to eliminate the call to this function, to be able to write for exemple... :
Singleton->Foo();
... using the class name the same way I use a variable, because of the singleton pattern, and others security like deleting the public constructor for exemple, we are sure that we only have a single instance, so why not "using the class as a variable" (quote, unquote, only syntaxic speaking of course !).
Each time, a C++ rule prohibit following exemples :
Singleton->Foo(); // (1)
Singleton()->Foo(); // (2)
Singleton.Foo(); // (3)
Singleton::Foo(); // (4)
Because :
- (1)
static Singleton* operator->() { return instance; }
is impossible, Class Member Access Operator (->) overload can't be static (see C2801), same for (2) with operator () - (3) and (4) operators . and :: can't be overloaded
Only solution here : Macros, but I'm actually using macros, and I want to find an other way and avoiding macros for this...
It's only a syntaxic interrogation, I'm not here to debate about pros and cons of singletons, but I wonder why C++ permit so many things for simplify the use syntax of users classes with overloads, user literals, and we can't eliminate this little function from the pattern.
I don't expect a solution (but if there is one, it would be great), it's just to understand why, to know if there is a explanation, a design reason, a security reason or anything else !
Thanks in advance !
c++ singleton
c++ singleton
asked Nov 11 at 0:48
Monk
143
143
1
BTW, This method comes strongly recommended: stackoverflow.com/a/1008289/3807729
– Galik
Nov 11 at 0:54
You can hide a singleton with a façade of static class functions, e.g.,static void Foo() { GetInstance()->Foo(); }
, then the callsite would only have to doSingleton::Foo();
which is pretty close to (4).
– Eljay
Nov 11 at 0:59
@Galik, interesting link, thanks. But i will go a little it further : I understand that this method can be important for destruction explained in your link, and in fact, I do not want to remove it from the class, only from the user code. Admit that operator -> can be static I could write :static Singleton* operator->() { return GetInstance(); }
, and useSingleton->Foo();
, the problem is not the existence of the method, but the call to this method in user code !
– Monk
Nov 11 at 1:03
@Eljay It's what I've thinking, but it mean that we always have to change all methods of all singletons class to statics methods or duplicate all publics methods to get a static version calling a non static version of the method... It's why I just speak of syntax, I don't want to change meaning of the existing code !
– Monk
Nov 11 at 1:06
There is a different pattern called the Monostate pattern. Very similar to a Singleton. All the functions are static functions ("class functions"), and all the data is in static variables ("class variables"). Any instances are empty, so usage just acts as a proxy for the class functions and class variables.
– Eljay
Nov 11 at 13:32
add a comment |
1
BTW, This method comes strongly recommended: stackoverflow.com/a/1008289/3807729
– Galik
Nov 11 at 0:54
You can hide a singleton with a façade of static class functions, e.g.,static void Foo() { GetInstance()->Foo(); }
, then the callsite would only have to doSingleton::Foo();
which is pretty close to (4).
– Eljay
Nov 11 at 0:59
@Galik, interesting link, thanks. But i will go a little it further : I understand that this method can be important for destruction explained in your link, and in fact, I do not want to remove it from the class, only from the user code. Admit that operator -> can be static I could write :static Singleton* operator->() { return GetInstance(); }
, and useSingleton->Foo();
, the problem is not the existence of the method, but the call to this method in user code !
– Monk
Nov 11 at 1:03
@Eljay It's what I've thinking, but it mean that we always have to change all methods of all singletons class to statics methods or duplicate all publics methods to get a static version calling a non static version of the method... It's why I just speak of syntax, I don't want to change meaning of the existing code !
– Monk
Nov 11 at 1:06
There is a different pattern called the Monostate pattern. Very similar to a Singleton. All the functions are static functions ("class functions"), and all the data is in static variables ("class variables"). Any instances are empty, so usage just acts as a proxy for the class functions and class variables.
– Eljay
Nov 11 at 13:32
1
1
BTW, This method comes strongly recommended: stackoverflow.com/a/1008289/3807729
– Galik
Nov 11 at 0:54
BTW, This method comes strongly recommended: stackoverflow.com/a/1008289/3807729
– Galik
Nov 11 at 0:54
You can hide a singleton with a façade of static class functions, e.g.,
static void Foo() { GetInstance()->Foo(); }
, then the callsite would only have to do Singleton::Foo();
which is pretty close to (4).– Eljay
Nov 11 at 0:59
You can hide a singleton with a façade of static class functions, e.g.,
static void Foo() { GetInstance()->Foo(); }
, then the callsite would only have to do Singleton::Foo();
which is pretty close to (4).– Eljay
Nov 11 at 0:59
@Galik, interesting link, thanks. But i will go a little it further : I understand that this method can be important for destruction explained in your link, and in fact, I do not want to remove it from the class, only from the user code. Admit that operator -> can be static I could write :
static Singleton* operator->() { return GetInstance(); }
, and use Singleton->Foo();
, the problem is not the existence of the method, but the call to this method in user code !– Monk
Nov 11 at 1:03
@Galik, interesting link, thanks. But i will go a little it further : I understand that this method can be important for destruction explained in your link, and in fact, I do not want to remove it from the class, only from the user code. Admit that operator -> can be static I could write :
static Singleton* operator->() { return GetInstance(); }
, and use Singleton->Foo();
, the problem is not the existence of the method, but the call to this method in user code !– Monk
Nov 11 at 1:03
@Eljay It's what I've thinking, but it mean that we always have to change all methods of all singletons class to statics methods or duplicate all publics methods to get a static version calling a non static version of the method... It's why I just speak of syntax, I don't want to change meaning of the existing code !
– Monk
Nov 11 at 1:06
@Eljay It's what I've thinking, but it mean that we always have to change all methods of all singletons class to statics methods or duplicate all publics methods to get a static version calling a non static version of the method... It's why I just speak of syntax, I don't want to change meaning of the existing code !
– Monk
Nov 11 at 1:06
There is a different pattern called the Monostate pattern. Very similar to a Singleton. All the functions are static functions ("class functions"), and all the data is in static variables ("class variables"). Any instances are empty, so usage just acts as a proxy for the class functions and class variables.
– Eljay
Nov 11 at 13:32
There is a different pattern called the Monostate pattern. Very similar to a Singleton. All the functions are static functions ("class functions"), and all the data is in static variables ("class variables"). Any instances are empty, so usage just acts as a proxy for the class functions and class variables.
– Eljay
Nov 11 at 13:32
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
Well one way to do this is to reduce the singleton part of the problem to just the data and create static functions that access that data through the "instance" function (called self()
in this example):
class Singletonish
{
private:
// single (inaccessible) instance of the data
static auto& self()
{
static struct {
std::string s = "unset";
int i = 0;
} data;
return data;
}
public:
static void foo()
{
// foo code here
self().s = "hello";
self().i = 9;
}
static void woo()
{
// woo code here
std::cout << self().s << 'n';
std::cout << self().i << 'n';
}
};
int main()
{
Singletonish::woo();
Singletonish::foo();
Singletonish::woo();
}
Output:
unset
0
hello
9
Personally I recommend just doing it the normal way: https://stackoverflow.com/a/1008289/3807729
For the sake of ensuring readability, maintainability, and frankly, sanity, I second your closing personal stance.
– WhozCraig
Nov 11 at 1:19
add a comment |
up vote
0
down vote
I can think of the following way in C++11
:
#include <memory>
struct singleton
{
int i;
};
template <class Singleton_t>
struct singleton_holder
{
auto* operator -> () const noexcept
{
static Singleton_t s;
return std::addressof(s);
}
};
// optional C++14 feature, can be commented if wanted
template <class Singleton_t>
constexpr const static /* inline */ singleton_holder<Singleton_t> singleton_v{};
Now, with this code, you can just create singleton_holder<singleton> s
and use s->i
to access the member of the singleton
directly.
Or you can use C++14
way: singleton_v<singleton>->i
to access member of the singleton
directly.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Well one way to do this is to reduce the singleton part of the problem to just the data and create static functions that access that data through the "instance" function (called self()
in this example):
class Singletonish
{
private:
// single (inaccessible) instance of the data
static auto& self()
{
static struct {
std::string s = "unset";
int i = 0;
} data;
return data;
}
public:
static void foo()
{
// foo code here
self().s = "hello";
self().i = 9;
}
static void woo()
{
// woo code here
std::cout << self().s << 'n';
std::cout << self().i << 'n';
}
};
int main()
{
Singletonish::woo();
Singletonish::foo();
Singletonish::woo();
}
Output:
unset
0
hello
9
Personally I recommend just doing it the normal way: https://stackoverflow.com/a/1008289/3807729
For the sake of ensuring readability, maintainability, and frankly, sanity, I second your closing personal stance.
– WhozCraig
Nov 11 at 1:19
add a comment |
up vote
1
down vote
Well one way to do this is to reduce the singleton part of the problem to just the data and create static functions that access that data through the "instance" function (called self()
in this example):
class Singletonish
{
private:
// single (inaccessible) instance of the data
static auto& self()
{
static struct {
std::string s = "unset";
int i = 0;
} data;
return data;
}
public:
static void foo()
{
// foo code here
self().s = "hello";
self().i = 9;
}
static void woo()
{
// woo code here
std::cout << self().s << 'n';
std::cout << self().i << 'n';
}
};
int main()
{
Singletonish::woo();
Singletonish::foo();
Singletonish::woo();
}
Output:
unset
0
hello
9
Personally I recommend just doing it the normal way: https://stackoverflow.com/a/1008289/3807729
For the sake of ensuring readability, maintainability, and frankly, sanity, I second your closing personal stance.
– WhozCraig
Nov 11 at 1:19
add a comment |
up vote
1
down vote
up vote
1
down vote
Well one way to do this is to reduce the singleton part of the problem to just the data and create static functions that access that data through the "instance" function (called self()
in this example):
class Singletonish
{
private:
// single (inaccessible) instance of the data
static auto& self()
{
static struct {
std::string s = "unset";
int i = 0;
} data;
return data;
}
public:
static void foo()
{
// foo code here
self().s = "hello";
self().i = 9;
}
static void woo()
{
// woo code here
std::cout << self().s << 'n';
std::cout << self().i << 'n';
}
};
int main()
{
Singletonish::woo();
Singletonish::foo();
Singletonish::woo();
}
Output:
unset
0
hello
9
Personally I recommend just doing it the normal way: https://stackoverflow.com/a/1008289/3807729
Well one way to do this is to reduce the singleton part of the problem to just the data and create static functions that access that data through the "instance" function (called self()
in this example):
class Singletonish
{
private:
// single (inaccessible) instance of the data
static auto& self()
{
static struct {
std::string s = "unset";
int i = 0;
} data;
return data;
}
public:
static void foo()
{
// foo code here
self().s = "hello";
self().i = 9;
}
static void woo()
{
// woo code here
std::cout << self().s << 'n';
std::cout << self().i << 'n';
}
};
int main()
{
Singletonish::woo();
Singletonish::foo();
Singletonish::woo();
}
Output:
unset
0
hello
9
Personally I recommend just doing it the normal way: https://stackoverflow.com/a/1008289/3807729
answered Nov 11 at 1:16
Galik
33k34674
33k34674
For the sake of ensuring readability, maintainability, and frankly, sanity, I second your closing personal stance.
– WhozCraig
Nov 11 at 1:19
add a comment |
For the sake of ensuring readability, maintainability, and frankly, sanity, I second your closing personal stance.
– WhozCraig
Nov 11 at 1:19
For the sake of ensuring readability, maintainability, and frankly, sanity, I second your closing personal stance.
– WhozCraig
Nov 11 at 1:19
For the sake of ensuring readability, maintainability, and frankly, sanity, I second your closing personal stance.
– WhozCraig
Nov 11 at 1:19
add a comment |
up vote
0
down vote
I can think of the following way in C++11
:
#include <memory>
struct singleton
{
int i;
};
template <class Singleton_t>
struct singleton_holder
{
auto* operator -> () const noexcept
{
static Singleton_t s;
return std::addressof(s);
}
};
// optional C++14 feature, can be commented if wanted
template <class Singleton_t>
constexpr const static /* inline */ singleton_holder<Singleton_t> singleton_v{};
Now, with this code, you can just create singleton_holder<singleton> s
and use s->i
to access the member of the singleton
directly.
Or you can use C++14
way: singleton_v<singleton>->i
to access member of the singleton
directly.
add a comment |
up vote
0
down vote
I can think of the following way in C++11
:
#include <memory>
struct singleton
{
int i;
};
template <class Singleton_t>
struct singleton_holder
{
auto* operator -> () const noexcept
{
static Singleton_t s;
return std::addressof(s);
}
};
// optional C++14 feature, can be commented if wanted
template <class Singleton_t>
constexpr const static /* inline */ singleton_holder<Singleton_t> singleton_v{};
Now, with this code, you can just create singleton_holder<singleton> s
and use s->i
to access the member of the singleton
directly.
Or you can use C++14
way: singleton_v<singleton>->i
to access member of the singleton
directly.
add a comment |
up vote
0
down vote
up vote
0
down vote
I can think of the following way in C++11
:
#include <memory>
struct singleton
{
int i;
};
template <class Singleton_t>
struct singleton_holder
{
auto* operator -> () const noexcept
{
static Singleton_t s;
return std::addressof(s);
}
};
// optional C++14 feature, can be commented if wanted
template <class Singleton_t>
constexpr const static /* inline */ singleton_holder<Singleton_t> singleton_v{};
Now, with this code, you can just create singleton_holder<singleton> s
and use s->i
to access the member of the singleton
directly.
Or you can use C++14
way: singleton_v<singleton>->i
to access member of the singleton
directly.
I can think of the following way in C++11
:
#include <memory>
struct singleton
{
int i;
};
template <class Singleton_t>
struct singleton_holder
{
auto* operator -> () const noexcept
{
static Singleton_t s;
return std::addressof(s);
}
};
// optional C++14 feature, can be commented if wanted
template <class Singleton_t>
constexpr const static /* inline */ singleton_holder<Singleton_t> singleton_v{};
Now, with this code, you can just create singleton_holder<singleton> s
and use s->i
to access the member of the singleton
directly.
Or you can use C++14
way: singleton_v<singleton>->i
to access member of the singleton
directly.
answered Nov 11 at 1:46
JiaHao Xu
511213
511213
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244857%2fsingleton-avoid-getintance%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
BTW, This method comes strongly recommended: stackoverflow.com/a/1008289/3807729
– Galik
Nov 11 at 0:54
You can hide a singleton with a façade of static class functions, e.g.,
static void Foo() { GetInstance()->Foo(); }
, then the callsite would only have to doSingleton::Foo();
which is pretty close to (4).– Eljay
Nov 11 at 0:59
@Galik, interesting link, thanks. But i will go a little it further : I understand that this method can be important for destruction explained in your link, and in fact, I do not want to remove it from the class, only from the user code. Admit that operator -> can be static I could write :
static Singleton* operator->() { return GetInstance(); }
, and useSingleton->Foo();
, the problem is not the existence of the method, but the call to this method in user code !– Monk
Nov 11 at 1:03
@Eljay It's what I've thinking, but it mean that we always have to change all methods of all singletons class to statics methods or duplicate all publics methods to get a static version calling a non static version of the method... It's why I just speak of syntax, I don't want to change meaning of the existing code !
– Monk
Nov 11 at 1:06
There is a different pattern called the Monostate pattern. Very similar to a Singleton. All the functions are static functions ("class functions"), and all the data is in static variables ("class variables"). Any instances are empty, so usage just acts as a proxy for the class functions and class variables.
– Eljay
Nov 11 at 13:32