質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1004閲覧

シングルトン以外の良い方法が知りたい

Scotch1536

総合スコア1

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/08/20 14:51

前提・実現したいこと

シングルトンは実体を一つに保証してかつグローバルにアクセスできるものだとおもうのですが

実体を一つに保証してかつ実体を定義したスコープ内でのみアクセスできるようにする最適な方法が知りたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/08/21 09:01 編集

この場合のスコープ、定義、およびカプセル化は何を意味していますか?
Zuishin

2020/08/21 09:14 編集

通常「実体を定義」はクラス定義ではなく、インスタンス化することを指します。オブジェクトを他の関数の引数として渡した場合、実体を定義したスコープの範囲外となるので、アクセスできてはいけません。つまりそのオブジェクトは引数として渡せないオブジェクトになります。 「カプセル化」については何をそう呼んでいるのか皆目見当がつきません。 また、目的がよくわかりませんが、その目的を果たすのにスマートポインタでは不足なんでしょうか?
fana

2020/08/21 10:27

どんな場面において,どのようなことをしたいと考えているのか? という事柄がわかる例が欲しいところですね.
Scotch1536

2020/08/22 16:59

どんな場面などの状況のことはあまり考えていませんでした、色々な例が知りたかったのであえてあいまいな質問にしてしまいましたが説明が不足しすぎていました、申し訳ないです。
Scotch1536

2020/08/22 17:02

この質問は単純にシングルトンは便利だけどグローバルにアクセスできるから アクセス制限できてかつシングルトンみたいに実体?定義?を一つだけに保証できる コーディング法がしりたかった。
Zuishin

2020/08/22 23:21

ブロックの中でシングルトン作ればいいだけ。
Zuishin

2020/08/22 23:22

さすがにそんな分かり切ったことは聞かないだろうと深読みしすぎたかな。
guest

回答2

0

ベストアンサー

何がしたいのかイマイチわかりませんが…

あるスコープの中だけの話ならば,「実体を一つ」くらいのことは,プログラマが2つ作らないように気を付ければよいのではないかと思うのですが,どうなんでしょう?

一応,「プログラマが気を付けることにするが,うっかりミスった場合には例外が出る」ようなのを↓に書いてみましたが,とても馬鹿馬鹿しい物だと思います.

C++

1void f( int NewValue ) 2{ 3 //... 4 5 {//このスコープの中でA型のインスタンスはTheAだけであり,且つ,スコープを抜けてもTheAは存在しつづける 6 class A 7 { 8 public: 9 A( int v=0 ) : m_Value(v) 10 { 11 //うっかり2個目を作ろうとすると例外が出る 12 static bool f = false; 13 if( f )throw std::runtime_error( "Can not create 2nd instance" ); 14 f = true; 15 } 16 17 //※その他の生成方法を適切に潰してください 18 A( const A& ) = delete; 19 20 // 21 int m_Value; 22 }; 23 static A TheA; 24 25 // 26 std::cout << "PrevValue : " << TheA.m_Value << std::endl; 27 28 TheA.m_Value = NewValue; 29 std::cout << "CurrValue : " << TheA.m_Value << std::endl; 30 } 31 32 //... 33} 34 35// 36int main(void) 37{ 38 //Test 39 f(1); 40 f(2); 41 f(3); 42 return 0; 43}

追記:
用途というかやりたいこと次第では,単にこれで済むかも?

C++

1// 2//何らかの.cpp 3// 4 5namespace 6{ 7 class SingletonClass { ... }; //シングルトンなクラス 8} 9 10//↑のSingletonClassは「このcpp内」からのみアクセスできる.

投稿2020/08/21 01:36

編集2020/08/21 10:33
fana

総合スコア11954

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Scotch1536

2020/08/21 08:52

コンストラクタに静的ローカル変数でフラグを設ければ確かに可能ですね スマートな技法があれば知りたいなという気持ちで質問しました、プログラマーに気をつけさせるのはカプセル化できてない証拠だと思っているので...
fana

2020/08/21 10:35

とりあえず,namespaceを追記しておきました. シングルトンにアクセスできる範囲を制限したいだけならば,この程度の話でも良いのかもしれません.
Scotch1536

2020/08/22 16:58

私も最初に思いついたのはその方法でした、ただファイルを分けたいときなどの例も知りたかったので 一つ目の回答は参考になりましたありがとうございます。
fana

2020/08/23 01:48

> ファイルを分けたいとき とは,具体的にはどのような話でしょうか?
Scotch1536

2020/08/23 08:34

例えばWinMain関数内でのみGameクラスをあつかいたい(実体を一つしか作れないよう制限されている) という場合でお願いします 補足 WinMainはmain.cppにあってGameクラスはGame.h,Game.cppで分けて書きたいって感じです
Zuishin

2020/08/23 08:36 編集

定義されるスコープが違うじゃないか。WinMain でしか使えないようにしたいなら WinMain で定義しないと質問の要件は満たせない。
fana

2020/08/23 09:33

本当に,「ある型(Gameクラス)の存在が特定のスコープ(WinMain)内からでしか見えず,且つその型の実態は1つしか作れないこと」を強制せねばならないものでしょうか? という疑問があるけども, それはそれとして… Game.h というファイルが存在するならば,それを誰かがどこかで「勝手にinclude」することを止めることはできないように思う. で,Game.hに書かれている何かに対して「WinMainしか扱えないという縛り」を設ける手段は無いんじゃないかな,と思うので, > Game.h,Game.cppで分けて書きたい というのは無理なんじゃないかな,と.
Scotch1536

2020/08/23 10:54

そうですよね... となるとfanaさんの最初の回答が変ではないし一番しっくりくるかな...
Scotch1536

2020/08/23 10:59

やっぱりそこまで制限する必要ってあんまりないんですかね(笑) そこらへんはプログラマーが気を付ける領域なのでしょうか、
Scotch1536

2020/08/23 11:05

今後複数人での制作も控えているんでできるだけコンパイルの時点でエラーが出るように しようしようと考えてしまって(汗
fana

2020/08/24 01:19

・本当にそれはシングルトンであるべきか?(2個目のインスタンスを作ったらもうその時点でまずいのか?) ・あなたの書いたGameクラスにアクセスするためには,他者は「わざわざ」#include "Game.h" とか書く必要があるわけで,それは「ついうっかり」とかではなく意図的な行為である. あなたがちゃんと「これはお前に公開する意図はない」と告げているのにもかかわらず,それを行う者とは協力して物を作っていくことはできないのではないかと思う.
Scotch1536

2020/08/27 04:45

その通りだと思いましたw
fana

2020/08/27 05:22

> できるだけコンパイルの時点でエラーが出るように 必要な心がけであると思いますが, ・本当にシングルトンであるべきならそうする ・そうでもなくて,コピーがまずいようならコピーを作れなくする くらいで良いんじゃないかな,と. (あとは,他のメンバーがあなたと同じくらい物事を心がけるであろうことに期待,という感じで)
guest

0

フレンド関数じゃだめですか?

投稿2020/08/23 09:53

bjnes

総合スコア113

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Scotch1536

2020/08/23 10:51

可能ではあるでしょうね.... あまり使用したくはありませんが(汗
fana

2020/08/24 01:42

そのフレンド関数と同名で同型の関数が存在する名前空間を作り,その内側で #include "Game.h" とかすることで使い放題になりませんか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問