C++でのリフレクションメカニズムの実装に取り組んでいます。私のコード内のすべてのオブジェクトは、Classクラスの静的メンバーデータムを含むObject(私の独自のジェネリックタイプ)のサブクラスです。
class Class{
public:
Class(const std::string &n, Object *(*c)());
protected:
std::string name; // Name for subclass
Object *(*create)(); // Pointer to creation function for subclass
};
静的なClassメンバーデータムを持つObjectのすべてのサブクラスについて、そのサブクラスのコンストラクターへのポインターで 'create'を初期化できるようにしたいと思います。
コンストラクタのアドレスは取得できません(C++ 98標準12.1/12コンストラクタ-「12.1-12コンストラクタ-「コンストラクタのアドレスは取得できません。」)
最善の策は、Object
を作成し、ファクトリのアドレスを渡すファクトリ関数/メソッドを用意することです。
class Object;
class Class{
public:
Class(const std::string &n, Object *(*c)()) : name(n), create(c) {};
protected:
std::string name; // Name for subclass
Object *(*create)(); // Pointer to creation function for subclass
};
class Object {};
Object* ObjectFactory()
{
return new Object;
}
int main(int argc, char**argv)
{
Class foo( "myFoo", ObjectFactory);
return 0;
}
私はこれと同じ問題に遭遇しました。私の解決策は、コンストラクターを呼び出すテンプレート関数でした。
template<class T> MyClass* create()
{
return new T;
}
これを関数ポインタとして使用するのは簡単です:
MyClass* (*createMyClass)(void) = create<MyClass>;
MyClassのインスタンスを取得するには:
MyClass* myClass = createMyClass();
ラムダスタイル:
[](){return new YourClass();}
うーん、奇妙です。 create
はメンバー変数です。つまり、クラスインスタンスでのみ使用できますが、その意図は、最初にインスタンスを作成することです。
コンストラクタのアドレスを取得することはできませんが、独自の静的ファクトリメソッドを作成して、そのアドレスを取得することができます。
メソッドでは通常の関数ポインターを使用できません。奇妙な構文を持つメソッドポインターを使用する必要があります。
void (MyClass::*method_ptr)(int x, int y);
method_ptr = &MyClass::MyMethod;
これにより、MyClassのメソッド(MyMethod)へのメソッドポインターが提供されます。ただし、これは絶対メモリアドレスではないという点で真のポインタではありません。基本的には、クラスへのオフセット(仮想継承のためにそれよりも複雑ですが、実装固有のものです)です。したがって、メソッドポインターを使用するには、次のようにクラスを指定する必要があります。
MyClass myclass;
myclass.*method_ptr(x, y);
または
MyClass *myclass = new MyClass;
myclass->*method_ptr(x, y);
もちろん、現時点では、メソッドポインターを使用してオブジェクトコンストラクターを指すことができないことは明らかです。メソッドポインターを使用するには、クラスのインスタンスが必要であり、そのコンストラクターは既に呼び出されています。したがって、あなたのケースでは、マイケルのオブジェクトファクトリの提案がおそらくそれを行うための最良の方法です。