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

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

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

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

Q&A

解決済

2回答

640閲覧

C++ オブジェクト思考でクラス間の変数を参照しあいたい

nicoyou

総合スコア129

C++

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

0グッド

0クリップ

投稿2019/07/20 09:54

C++でオブジェクト思考でクラス間の変数を参照しあいたいです
そのために考えた方法は、プロジェクトで一つstaticでデータを保管するクラス(dataとする)を作成し、
classAでデータが更新されたらdataに渡し、classBでデータが必要になればdataから引っ張ってくるというものです
その為にどの様な形式のデータでも保存でき、保存されているデータを引き出すときに保存する時に指定したid(文字列)を指定して引き出せるというdata classを実装したいです
また、不要になった時にidから削除、すべて開放等の機能も欲しいです
このようなクラスを定義する方法を教えていただければ嬉しいです

また、どうしても抽象的な質問となってしまうのですが、オブジェクト思考としてデータを参照しあうもっといい方法があれば指摘していただければ嬉しいです

VC++2017 win10

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

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

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

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

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

nicoyou

2019/07/20 10:36

完全なオブジェクト思考で作成したいわけではなく、あくまでもゲームを作るうえでオブジェクト思考を意識して作っているという程度です 勘違いはしておりませんが、よく理解しているというわけではないので書き方は正しくないかもしれません
guest

回答2

0

こんにちは。

オブジェクト指向プログラミングは、「オブジェクト」を中心に「据えて」設計します。
まず、何をオブジェクトとするのか、各オブジェクトにはどのような役割を与えるのか、どのオブジェクトとどのオブジェクトが関係を持ち、どのような要求と応答を担うのか、などなどを設計します。
これらの設計をおざなりにした「オブジェクト指向プログラミング」はありえません。

プロジェクトで一つstaticでデータを保管するクラス(dataとする)を作成し、classAでデータが更新されたらdataに渡し、classBでデータが必要になればdataから引っ張ってくるというものです

という検討の中に「オブジェクト」の役割について一切含まれていないので、これは「オブジェクト指向プログラミング」ではないです。

そもそも、staticメンバ変数は要するにグローバル変数ですから、一般に避けることが出来る時には避けるべきものです。どうしても必要な時のみ採用することが推奨されます。

オブジェクト思考としてデータを参照しあうもっといい方法があれば指摘していただければ嬉しいです

それぞれのオブジェクトがどのような特性を持っているのか、どのようなタイミングで参照するのかなどなど、状況によって使える方法や望ましい方法は異なります。

ご質問のように設計が抽象的な段階で具体的な方法を検討すると、全てが可能な手法を使うことになり、それには一切のバグ検出能力がありません。オブジェクト指向プログラミングは、不要なことを出来ないようにしたり、書きにくくしたりすることによりバグを早期発見できる優れものです。
ですので、もっと具体的な設計まで落とし込んで、何が必要で何が不要なのか明確化してから、検討を始めることをお勧めします。

投稿2019/07/20 11:44

Chironian

総合スコア23272

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

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

nicoyou

2019/07/20 12:15

ご回答ありがとうございます オブジェクト指向についてはgameの設計の時に各オブジェクト(敵とか球とか)をそれぞれ独立させて(class)考える等物をイメージしていました ただ、独立させたのはいいものの、各オブジェクトで互いの座標が必要なため、どうしようかと考えている最中です >オブジェクト指向プログラミングは、不要なことを出来ないようにしたり、書きにくくしたりすることによりバグを早期発見できる優れものです。 一応これは理解しているつもりなのですがまだ経験がないに等しく、非常に難しいです
Chironian

2019/07/20 13:44

そのようなケースでは、「位置」を保持するような基底クラスを用意して、敵とか珠をその基底クラスから派生させ、当該基底クラスを保持する std::unique_ptrをstd::vectorで管理することが考えられます。 当該std::vectorのインスタンスをグローバル変数にすることで、全ての敵や珠が、他の敵や珠の位置をアクセスできるようになります。 もし、上記のstd::vectorのインスタンスへアクセスできるオブジェクトを限定したい場合は、グローバル変数とは異なる設計が必要になります。これもやはりケースバイケースです。 何にせよ、具体的に設計しないとオブジェクト指向は役に立ちません。具体的設計無しにオブジェクト指向を適用しようとするから「非常に難しいです」かもしれないですよ。
nicoyou

2019/07/20 14:07

詳しい解説を有難うございます 頂いた説明を参考に試行錯誤しますm(__)m
guest

0

ベストアンサー

その為にどの様な形式のデータでも保存でき、保存されているデータを引き出すときに保存する時に指定したid(文字列)を指定して引き出せるというdata classを実装したいです
また、不要になった時にidから削除、すべて開放等の機能も欲しいです

文字通りの要件を満たすクラスは、C++17標準ライブラリを用いて実現可能です。https://wandbox.org/permlink/5zeAYeOkgJuJgVwQ

C++

1#include <string> 2#include <map> 3#include <any> 4#include <iostream> 5 6// std::stringリテラル 7using namespace std::string_literals; 8 9// 文字列をキーにあらゆるデータ型を格納できるマップ 10using AnyMapType = std::map<std::string, std::any>; 11 12AnyMapType global_vars; 13 14 15int main() 16{ 17 // "number"をキーに値42を格納 18 global_vars["number"s] = 42; 19 // "greeting"をキーに文字列"Hello"を格納 20 global_vars["greeting"s] = "Hello"s; 21 22 // キー"number"をもつ数値を取り出し 23 auto number = std::any_cast<int>(global_vars["number"s]); 24 std::cout << number << std::endl; 25 26 // キー"greeting"をもつ文字列を取り出し 27 auto greeting = std::any_cast<std::string>(global_vars["greeting"s]); 28 std::cout << greeting << std::endl; 29 30 // キー"greeting"を削除(文字列"Hello"は自動的に解放される) 31 global_vars.erase("greeting"s); 32 33 try { 34   // 削除済みのキー"greeting"をもつ文字列を取り出そうとすると... 35 auto greeting = std::any_cast<std::string>(global_vars["greeting"s]); 36 std::cout << greeting << std::endl; 37 } catch (std::bad_any_cast&) { 38 // 例外std::bad_any_castが送出される 39 std::cout << "(No greeting)" << std::endl; 40 } 41}

オブジェクト思考としてデータを参照しあうもっといい方法があれば指摘していただければ嬉しいです

プログラムの設計は、具体的な問題の解決手段をさぐるモデリング作業です。残念ながら、あなたの質問内容からは「ケース・バイ・ケースですね」としかお答えできません。

確実に言えるのは、前掲のような「文字列をキーとして何でも格納できるデータ型」は、C++言語としては 非常にまずい設計 です。何でもできる=自由度が高すぎる設計では、あらゆることがプログラマの責任になっています。

先ほどのプログラムでうっかりキー名を間違えたら?うっかり対応するデータ型を間違えたら?誰かが勝手にデータを書き換えたら?C++コンパイラは何も助けてくれません。

P.S. 念のため、"オブジェクト思考"→"オブジェクト指向"ですね。

投稿2019/07/20 10:35

yohhoy

総合スコア6189

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

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

nicoyou

2019/07/20 10:41

ご回答ありがとうございます >確実に言えるのは、前掲のような「文字列をキーとして何でも格納できるデータ型」は、C++言語としては 非常にまずい設計 です。何でもできる=自由度が高すぎる設計では、あらゆることがプログラマの責任になっています。 そうなんですね、覚えておきます あらかじめ使用する型をclassで最初にすべてstatic宣言するといった形のほうがまだよいでしょうか... >"オブジェクト思考"→"オブジェクト指向"ですね。 深く考えずただただ、変換キーを一度押しておりました 気をつけますm(__)m コードの方は調べながら理解したいのでもう少し時間をください
nicoyou

2019/07/20 14:12

ベストアンサーは先に質問の内容であるコードをいただいたのでyohhoyさんを選ばさせていただきます お二方ありがとうございましたm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問