2

c++で渡された型名(文字列)を使用してオブジェクトの見本を返すことは可能ですか? 基本抽象クラスBaseといくつかの派生クラスがあります。コード例:

class Base
{
   /* ... */
};

class Der1 : public Base
{
   /* ... */
};

class Der2 : public Base
{
   /* ... */
};

そして、次のような関数が必要です:

Base *objectByType(const std::string &name);

name派生クラスの数は変更可能であり、新しいオブジェクト型を手動で切り替えて返すようなことはしたくありません。とにかくC ++でそれを自動的に行うことは可能ですか?

ps の使用法は次のようになります。

dynamic_cast<Der1>(objectByType("Der1"));

純粋な C++ コード (クロスプラットフォーム) が必要です。ブーストの使用は許容されます。

4

6 に答える 6

2

これを C++ で行うことはできません。

1 つのオプションは、ファクトリを作成し、渡された名前をオンにすることですが、それをしたくないようです。C++ は、dynamic_cast 以外の実際のランタイム リフレクションをサポートしていないため、この種の問題は解決が困難です。

于 2011-01-16T11:51:02.560 に答える
2

のシーケンスなしでファクトリ メソッドを記述できる便利なトリックがありますif...else if...

(私の知る限り、このコードはコンパイル時に生成されるため、C ++で必要なことを行うことは実際には不可能であることに注意してください。この目的のために「ファクトリーメソッド」デザインパターンが存在します)

最初に、global repository派生クラスの を定義します。という形式std::map<std::string, Base*>、つまり、派生クラスの名前をそのクラスにマップすることができますan instance

派生クラスごとにdefault constructor、そのクラスのオブジェクトをクラスの名前でリポジトリに追加する を定義します。クラスの静的インスタンスも定義します。

// file: der1.h
#include "repository.h"

class Der1: public Base {
public:
  Der1() { repository[std::string("Der1")] = this; }
};

// file: der1.cpp
static Der1 der1Initializer;

静的変数のコンストラクターは の前でも実行されるmain()ため、main開始時には、すべての派生クラスのインスタンスでリポジトリが初期化されています。

ファクトリ メソッド (例: Base::getObject(const std::string&)) は、リポジトリ マップでクラス名を検索する必要があります。次に、clone()見つかったオブジェクトのメソッドを使用して、同じタイプの新しいオブジェクトを取得します。cloneもちろん、サブクラスごとに実装する必要があります。

このアプローチの利点は、新しい派生クラスを追加するときに、追加が新しいクラスを実装するファイルにのみ制限されることです。リポジトリとファクトリ コードは変更されません。もちろん、プログラムを再コンパイルする必要があります。

于 2011-01-16T12:41:53.593 に答える
0

はい、可能です!と呼ばれるこの非常に面白いクラスを確認してください。Activator すべてを作成できTypestringパラメーターのリストを与えることもできるため、メソッドは最適な引数セットで適切なコンストラクターを呼び出します。

于 2011-01-16T11:45:20.053 に答える
0

私が誤解していない限り、typeidキーワードは探しているものの一部である必要があります。

于 2011-01-16T11:49:43.400 に答える
0

それは不可能。objectByType関数を自分で作成する必要があります。

Base* objectByType(const std::string& name) {
  if (name == "Der1")
    return new Der1;
  else if (name == "Der2")
    return new Der2;
  // other possible tests
  throw std::invalid_argument("Unknown type name " + name);
}
于 2011-01-16T12:07:33.390 に答える
0

C++ はリフレクションをサポートしていません。

私の意見では、これが Java が C++ を凌駕する唯一のポイントです。
(これに対してあまりにも多くの反対票を獲得しないように...)

MOC が Qt に対して行うのと同様に、カスタム プリプロセッサを使用することで、そのようなことを実現できます。

于 2011-01-16T12:24:39.420 に答える