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

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

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

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

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

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

解決済

4回答

8478閲覧

C++でゲーム開発する際の設計について

tiwatiwa

総合スコア70

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

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

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

0グッド

6クリップ

投稿2015/06/24 16:11

C++で3Dゲーム開発を行っています。

現在、すべてをクラスとして設計(グローバル変数は禁止の自分ルール)しているのですが、プログラム内の変数や引数がC++のスマートポインタだらけになってしまっています。(shared_ptrとweak_ptrが大半です。)

スマートポインタを使って設計を行った場合にこうなるのは仕方のないことなのでしょうか?
また、スマートポインタを使わずにもっとバグが出にくくできたり、保守が容易になるような設計方法がありましたら、ご教授お願いします。

例えば、プログラム内の変数やクラスのポインタを持つだけのクラスを作って、それをクラス間で渡すことで引数の数を減らしたり、他クラスへのアクセスが容易になると考えたのですが、信頼性やプロから見た際の見栄えはどうなのかな?と思っています。(スマートポインタを使えば大丈夫なのかな?)

また、少し論点がずれるくらいは問題ないので、自分はこうやってるよ!みたいなことがあればよろしくお願いします。

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

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

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

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

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

guest

回答4

0

ベストアンサー

C++のスマートポインタ(shared_ptr, weak_ptr)は、インスタンスの所有権(ownership)を管理するものです。

C++プログラムにて所有権を扱う方法として、その他には下記が考えられます。いずれもshared_ptr<T>weak_ptr<T>より「軽量」な仕組みですから、必要に応じて利用検討してください。

(1) (スマートポインタではない)値型Tとしてメンバ変数を保持する。保持クラスのインスタンス生存期間=対象インスタンスの生存期間であり、保持クラスが対象インスタンスを所有する場合はこれがベストです。
(2) 関数の引数型として、スマートポインタの代わりに参照型(T&, const T&)をとる。インスタンスの所有権は関数呼び出し元に残っており、関数呼び出し中(≒呼び出し元は待機状態)だけインスタンスにアクセスさせるという考え方です。
(3) 所有権を共有する必要がなければ、shared_ptr<T>ではなくunique_ptr<T>を使うべきです。unique_ptr<T>の方が(アクセス時間・メモリ専有量ともに)実行時オーバーヘッドが小さくなります。なお、必要に応じてunique_ptr<T>からshared_ptr<T>へと変換可能です。

投稿2015/07/18 08:08

編集2015/07/18 08:10
yohhoy

総合スコア6189

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

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

0

あくまでも自分の場合ですが…

ポインタが増えるのは仕方ないのですが、なるべくクラス内に隠蔽して外に出さない仕組みを作ります。

関数の引数は、操作対象のオブジェクトへの参照とオプションの2つ3つで賄えることが多いので、引数が多くなったら減らせないか考えます。

それと同時に、ゲームの場合、インスタンスがひとつで良いものが多いので、その場合はあまりこだわらずにグローバルにします。グローバル変数はちょっと嫌なので、静的メンバなどで。これで引数で引き回す量が減ります。

投稿2015/06/25 03:09

編集2015/06/25 03:09
naga3

総合スコア1293

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

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

tiwatiwa

2015/06/25 10:00

>ポインタが増えるのは仕方ないのですが、なるべくクラス内に隠蔽して外に出さない仕組みを作ります。 やっぱり「なるべく」になってしまうのはしょうがないのでしょうか...
guest

0

3Dゲーとのことなので、速度やフレームレートの安定が重要であるという前提で考えると
何でもかんでもスマートポインタにしとこう、というのはちょっとマズイかもしれません。

MMORPGやオープンワールドゲームのように、必要になるリソースをしぼれない
(ワールドマップで遊んでいる最中にVRAMにロードしてないテクスチャが必要になる、新しいキャラクタが現れるなど)場合は仕方ないですが、
基本的にゲームはプレイ中に画面がガクつかない方がいいですよね。
なので基本的にプレイ中のヒープ確保は厳禁です。キャラクタクラス等はロード終了前に全て確保されているべきです。

同時に、テクスチャ等のGPUリソースも所有権を曖昧にせず、リソースを管理するクラスに一元管理させて
ロード画面のときに必要なものを全て読み、VRAMの空きに応じて不要なものを破棄すべきです。
あとリソースとゲーム内の概念のクラス(キャラクタ等)は分離してますでしょうか?
一般的には、リソースとキャラクタ等は癒着させない方がいいです。

決してスマートポインタを使うなという話ではないのですが、その辺の事情を加えれば、ご自身の開発に適したスマートポインタの種類、あるいは管理方法が浮かんでくるのではないでしょうか。

投稿2016/12/23 09:25

編集2016/12/24 05:43
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

私はゲームを作っていないので、文章中の例が的外れかもしれませんが

例えば、プログラム内の変数やクラスのポインタを持つだけのクラスを作って、それをクラス間で渡すことで引数の数を減らしたり、他クラスへのアクセスが容易になると考えたのですが、信頼性やプロから見た際の見栄えはどうなのかな?と思っています。(スマートポインタを使えば大丈夫なのかな?)

引数の設定が同じなら結果が必ず同じ、という場合構造体にまとめることはあります。
例えば、細かく装備品をカスタマイズするためのメソッドを作りたい!という場合には武器カスタマイズに関する注文書のイメージで構造体にまとめて渡します。
※RESTful APIと近いかな

他に引数を減らすためにしていることは、纏められる情報は纏めること、クラス自体を受け渡すのではなく、クラスのメソッドを呼び出すようにリファクタリングすることです。
簡単な例ですが、あるキャラクターの座標を変更する関数UpdatePosition(Character *character, int x, int y) があったとします。

これは、まず座標を構造体struct Point { int X, int Y } を作って短くできるでしょうし
UpdatePosition(Character *character, Point point)

UpdatePosition自体をCharacterクラスのメンバに含めることもできます。
void Character::UpdatePosition(Point point);
※座標情報(状態)をCharacterに持つべきではない場合もあるので、その場合は座標+キャラクターを管理するラップクラスを作ってそちらに委任します。

直接メソッドを呼び出す形式にできれば、クラス内の変数にアクセスする必要性が無くなりますし、メンバが晒されない=外部参照が減るということですから、weak_ptrも減るかもしれません。

投稿2015/07/16 09:29

haru666

総合スコア1591

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問