これは、「コードが機能せず、その理由がわかりません」という別の質問です。std::map::insert が例外をスローする理由を知るには、stl に関する十分な知識がありません。どのような場合に例外がスローされるかがわかっている場合は、おそらくこのテキストの壁をスキップして、答えることができます。問題の背景がどうしても必要な場合は、それを試してください。私のコードを投稿し、何が行われたかを説明します。 stl についてよりよく知っているすべての人が、挿入の呼び出しで何が問題なのかを説明できれば、非常に感謝しています。
go to factory オブジェクトとして時折使用するオブジェクトを少し前に書きました。その主な目的は、基本的に文字列を取得し、文字列と「新しいオブジェクト関数の作成」ポインターの両方を格納することです。これにより、最終的に関数を呼び出し、文字列を渡し、有効な登録がある場合は、派生オブジェクトの新しいインスタンスを返します。話が減り、コードが増えました。ここに私が得たものがあります:
factory.h
#ifndef FACTORY_H
#define FACTORY_H
// library tools
#include <map>
#include <string>
// Simplified registration macros
#define DECLARE_DERIVED(T, base) static Factory<base>::DerivedRegister<T> reg;
#define DEFINE_DERIVED(T, base, s) Factory<base>::DerivedRegister<T> T::reg(s);
template<class base>
class Factory
{
protected:
template<class T>
static base * createT() { return new T;}
public:
typedef std::map<std::string, base*(*)()> map_type;
virtual ~Factory(){ }
static base * createInstance(const std::string & s)
{
if(!m_Map.count(s))
return nullptr;
std::map<std::string, base*(*)()>::iterator it = m_Map.find(s);
return it->second();
}
template <class T>
struct DerivedRegister;
protected:
static map_type m_Map;
};
template<class base>
template<class T>
struct Factory<base>::DerivedRegister : public Factory<base>
{
DerivedRegister(std::string const & s)
{
m_Map.insert(std::pair<std::string, base*(*)()>(s, &createT<T>));
}
};
#endif
here は、それが本当に迅速に行うことのより良い説明です。基本クラス class A があるとします。そして、任意の数の派生クラスがあります。A にテンプレート化されたファクトリ オブジェクトをどこかに作成し、派生レジスタ オブジェクトを手動で作成するか、派生クラス宣言内の上部にあるマクロを使用して、静的レジストリ オブジェクトを作成します。次に、実装でそれを定義し、そのコンストラクターを呼び出して、オブジェクトの識別に使用する文字列を渡します。ファクトリ メンバーの createInstance を使用すると、文字列識別子を渡すことができ、A * が指す派生オブジェクトを返すことができます。
例:
ああ
class A
{
};
A.cpp
// the map for this factory template has to be defined somewhere, as it is static
Factory<A>::map_type Factory<A>::m_Map;
bh
#include <A.h>
class B : public A
{
// anywhere in declaration of derived B
DECLARE_DERIVED(A, B)
};
b.cpp
// just somewhere in cpp file
DEFINE_DERIVED(A, B, "B")
main.cpp
int main()
{
A * ptr;
Factory<A> factory;
ptr = factory.createInstance("B");
}
このオブジェクトは、過去にほとんど問題なく機能していました。今、私はもう少し複雑なプロジェクトを行っています。私はゲーム エンジンに関連するデータ編成/API 設計が好きで、(インスタンス化されていない) シェーダーをカタログ化するソリューションを実装しようとしています。プログラミングされていますが、必要な場合を除き、実行時にインスタンス化されません。それはさておき、この質問は実際にはd3d11とは何の関係もありません。少なくとも私はそうではないことを願っています.
これが何が起こっているかです。グラフィック シェーダーの抽象クラスを表すオブジェクトがあります。作成するすべてのシェーダーは、このオブジェクトから派生する必要があります。その機能から派生させて実装する方法は、すべてのシェーダーごとに異なります。
名前空間同期でベース オブジェクト「SYNC::D3D11Shader」を呼び出し、派生シェーダー「ColorShader」「LightShader」および「TextureShader」を呼び出しましょう。レンダリング オブジェクト内でこれらのシェーダーのインスタンスの std::map を単純に作成したくないので、このようにレンダリング オブジェクト内にファクトリを作成します。
D3D11Renderer.h
class D3D11Renderer
{
// many other members...
Factory<D3D11Shader> m_ShaderFactory;
// many other member...
};
D3D11Renderer.cpp
// define this templated classes map or you'll get undefined errors
Factory<SYNC::D3D11Shader>::map_type Factory<SYNC::D3D11Shader>::m_Map;
そして、ColorShader でマクロを次のように使用します。
D3D11ColorShader.h
class D3D11ColorShader : public SYNC::D3D11Shader
{
// ...lotsa members
DECLARE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader)
// lotsa member...
};
D3D11ColorShader.cpp
// define the registery object with it's key here
DEFINE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader, "ColorShader")
これはすべて正常にコンパイルされ、例外がスローされる場所は、特に挿入呼び出しで、D3D11ColorShader.cpp の registryObjects コンストラクターを最初に呼び出す場所です。例外エラーは次のとおりです。
Syncopate.exe の 0x772315de で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0x00000004。
したがって、実際には、問題は、いつ std::map::insert が例外をスローするのか、そしてその理由に要約されます。私がやっていることについて、誰もが何らかの背景を尋ねてくるだろうということはわかっていました。低く見よ、テキストの巨大な壁が現れた!私が本当に必要としているのは直感だけです。
また、質問は実際には関係ないので、d3d11にタグを付ける必要がありますか?