お世話になります。
デザインパターンのシングルトンをC++で実装/使用する際
friendが出てくるのが少し煩わしいと感じて、質問することにしました。
シングルトンパターンの実装として、下記サイトのコードを使用しています。
これでほぼ完璧! C++シングルトン基底クラスの決定版!
サイトの方法では、シングルトンクラスを継承してクラスを定義する際
定義するクラス内でfriendを指定する必要がありますが、
friendを書かずに実現する方法は、ないでしょうか?
書き忘れた場合でも、コンパイル時に気が付けますが
書かなくても実現できるのであれば、書かない方法を使いたいです。
宜しくお願い致します。
C++ もっとシンプルに使えるシングルトンクラス
Re: C++ もっとシンプルに使えるシングルトンクラス
オフトピック
素人の私には
Singleton<T>に書いている事柄を Hoge にダイレクトに書けばいいだけの話に見える…
この話に継承を用いる利点わからないです.
Singleton<T>に書いている事柄を Hoge にダイレクトに書けばいいだけの話に見える…
この話に継承を用いる利点わからないです.
Re: C++ もっとシンプルに使えるシングルトンクラス
継承を使用しているのは、
シングルトンの機能を再利用するためです。
プロジェクト内で、複数のクラスに対して
個別にシングルトンを実装していく手間を省きたい意図です。
シングルトンの機能を再利用するためです。
プロジェクト内で、複数のクラスに対して
個別にシングルトンを実装していく手間を省きたい意図です。
Re: C++ もっとシンプルに使えるシングルトンクラス
解決方法ではないのですが、
そもそもそのサイトのコードで、 friend を書くというのは、コンストラクタを private 指定することと1セットにして初めて意味があることです。
派生クラスのコンストラクタを private にする事を強制する方法が存在しないのであれば、(基底クラスを指定するだけ、という方法で)これ以上シンプルにするのは難しいのではないかなと思いますが、どうでしょうか。
そもそもそのサイトのコードで、 friend を書くというのは、コンストラクタを private 指定することと1セットにして初めて意味があることです。
派生クラスのコンストラクタを private にする事を強制する方法が存在しないのであれば、(基底クラスを指定するだけ、という方法で)これ以上シンプルにするのは難しいのではないかなと思いますが、どうでしょうか。
Re: C++ もっとシンプルに使えるシングルトンクラス
シンプルにする別の方向性として、CRTP を使わない(Singleton を基底にしない)のであれば書き忘れは防げるのではないかと思いました。
friend は残りますが、 Hoge がシングルトンであることは1回しか書かなくて済みます。
これだと、 createInstance がカスタムできない弱点がありますが…。
friend は残りますが、 Hoge がシングルトンであることは1回しか書かなくて済みます。
これだと、 createInstance がカスタムできない弱点がありますが…。
#include <memory>
class StaticOnly {
StaticOnly() = delete;
StaticOnly(const StaticOnly &) = delete;
StaticOnly &operator=(const StaticOnly &) = delete;
StaticOnly(StaticOnly &&) = delete;
StaticOnly &operator=(StaticOnly &&) = delete;
};
template <class T> using singleton_pointer_type = std::unique_ptr<T>;
template <class T> T &singleton();
template <class T> class SingletonSpy : public StaticOnly {
friend T &singleton<T>();
static T *createInstance() { return new T(); }
static T &getReference(const singleton_pointer_type<T> &ptr) { return *ptr; }
};
template <class T> T &singleton() {
static singleton_pointer_type<T> s(SingletonSpy<T>::createInstance());
return SingletonSpy<T>::getReference(s);
}
class Hoge {
friend SingletonSpy<Hoge>;
Hoge() {}
public:
void func() { puts("hoge"); }
};
int main() {
auto &hoge = singleton<Hoge>();
hoge.func();
//Hoge a; // compile error
//SingletonSpy<Hoge> b; // compile error
return 0;
}
Re: C++ もっとシンプルに使えるシングルトンクラス
結城紬さん、回答ありがとうございます!
実装例まで、あげていただき非常にわかりやすかったです。
使用側でシングルトンの記述を最小限に抑えたかったので、
ご提示いただいた方法で、十分でした。
おかげさまで、かなりシンプルに書けるようになりました。
ありがとうございました。
実装例まで、あげていただき非常にわかりやすかったです。
使用側でシングルトンの記述を最小限に抑えたかったので、
ご提示いただいた方法で、十分でした。
おかげさまで、かなりシンプルに書けるようになりました。
ありがとうございました。