自作マネージャー

アバター
TOMY
記事: 53
登録日時: 12年前
住所: 愛知県
連絡を取る:

自作マネージャー

投稿記事 by TOMY » 11年前

ゲーム用に作った各種メディアファイルとかを多重でロードしないように作ったマネージャーで不可解な動きが出てたのでいろいろデバックで1行ずつstl::map内の要素チェックしたりタスクマネージャのI/O読み取りバイト数チェックしてたりしたら、とんでもないポカやらかしてしかもそれに気づいてなかったことに気がついた。すっごい死にたくなった。
(比較して探してみよう)
//とんでもないポカやらかした方

CODE:

	if(m_AudioContainer.size() == 0){				//コンテナ内に要素が一つもなかったら作って返す(要素のチェックがあるので何も入っていない時の処理が必須)
		Media* Data = new Media();

		char* pFilename = StringfromCString(filename);
		Data->LoadFile(pFilename);

		m_AudioContainer[filename] = Data;
		return m_AudioContainer[filename];
	}

	for(m_AudioIterator = m_AudioContainer.begin() ; m_AudioIterator != m_AudioContainer.end() ; m_AudioIterator++){
		//KEYにすでに登録済みのFileNameがあったら、そのKEYに紐付けられたDATAのアドレスを返し、なければ作る。
		if((m_AudioIterator->first) == filename ){
			return m_AudioIterator->second;
		}else{
	                         //KEYに紐付けられたデータが無ければ新規で作って登録
	                Media* Data = new Media();
	                         char* pFilename = StringfromCString(filename);
	                         Data->LoadFile(pFilename);
	                         m_AudioContainer[filename] = Data;
	                         return m_AudioContainer[filename];
                          }
            }
//本当にやりたかった方

CODE:


	if(m_AudioContainer.size() == 0){				//コンテナ内に要素が一つもなかったら作って返す(要素のチェックがあるので何も入っていない時の処理が必須)
		Media* Data = new Media();

		char* pFilename = StringfromCString(filename);
		Data->LoadFile(pFilename);

		m_AudioContainer[filename] = Data;
		return m_AudioContainer[filename];
	}

	for(m_AudioIterator = m_AudioContainer.begin() ; m_AudioIterator != m_AudioContainer.end() ; m_AudioIterator++){
		//KEYにすでに登録済みのFileNameがあったら、そのKEYに紐付けられたDATAのアドレスを返し、なければ作る。
		if((m_AudioIterator->first) == filename ){
			return m_AudioIterator->second;
		}
	}
	//KEYに紐付けられたデータが無ければ新規で作って登録
	Media* Data = new Media();
	char* pFilename = StringfromCString(filename);
	Data->LoadFile(pFilename);
	m_AudioContainer[filename] = Data;
	return m_AudioContainer[filename];


最後に実装する前のコンソールアプリケーションをうp。

最後の最後にデバックで使っているタスクマネージャーの設定写真を上げてみる。
タスクマネージャーでメモリを見るのは鉄板


追記:就活浪人確定しました。
添付ファイル
taskmanager.png

[拡張子 zip は無効化されているため、表示できません]

最後に編集したユーザー TOMY on 2013年2月15日(金) 17:04 [ 編集 1 回目 ]

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前

Re: 自作マネージャー

投稿記事 by h2so5 » 11年前

登録済みかどうか調べるのに map::find を使っていないのは何故でしょうか?

アバター
TOMY
記事: 53
登録日時: 12年前
住所: 愛知県
連絡を取る:

Re: 自作マネージャー

投稿記事 by TOMY » 11年前

find
指定したキーと同じキーを持つマップに要素の位置を指定する反復子を返します。

コピー
iterator find(
const Key& _Key
);
const_iterator find(
const Key& _Key
) const;
パラメーター

--------------------------------------------------------------------------------

_Key
検索マップからの要素の並べ替えキーが一致するキー値。

戻り値

--------------------------------------------------------------------------------

一致するキーにある指定したキーを持つ要素の位置を指定する反復子、またはマップに最後の要素の次の場所。

解説

--------------------------------------------------------------------------------

このメンバー関数は、並べ替えキーが比較可能な関係によりも少ない基づいて命令を引き起こすバイナリ述語の下の引数のキーに対応するマップ要素を指定する反復子を返します。

find の戻り値が const_iteratorに割り当てられている場合、マップ オブジェクトは変更できません。 find の戻り値が [反復子]に割り当てられている場合、マップ オブジェクトは変更できます

こんな便利なのあったんだねぇ・・・本当に死にたい。

アバター
TOMY
記事: 53
登録日時: 12年前
住所: 愛知県
連絡を取る:

Re: 自作マネージャー

投稿記事 by TOMY » 11年前

まぁきっと無駄じゃないよ。きっと。・・・・うん。

YuO
記事: 947
登録日時: 13年前

Re: 自作マネージャー

投稿記事 by YuO » 11年前

反復子のインクリメントは,後置よりも前置が推奨されます。
後置は無駄なオブジェクト生成を必要とする場合があるためです。

あと,には便利な関数がたくさんあります。
今回のだとループを書くよりstd::find_ifを使う方がC++っぽいでしょう。
# よりメンバ関数の方が効率が良いため,キーの全探索ではstd::map::findの方がよいですが,一般構造としてはstd::find_ifになります。

アバター
TOMY
記事: 53
登録日時: 12年前
住所: 愛知県
連絡を取る:

Re: 自作マネージャー

投稿記事 by TOMY » 11年前

インクリメントの順番だけでも小さな問題が起こる可能性があるんですね・・・参考になるます。