5

C++ で C# typeof-command の動作をシミュレートする方法は?

C# の例:

public static PluginNodeList GetPlugins (Type type)
{
 ...
}

電話:

PluginManager.GetPlugins (typeof(IPlugin))

C++ を使用してこれを実装する方法は? おそらくQTまたはBoostライブラリが解決策を提供しますか?

ファイル (.so または .dll) からこれらの種類のオブジェクトをロードする方法で .GetPlugins(...) を実装したい場合はどうでしょうか?

4

8 に答える 8

7

以下に示すように、dynamic_cast を使用して型をテストできます。

IPlugin* iPluginPtr = NULL;
iPluginPtr = dynamic_cast<IPlugin*>(somePluginPtr);

if (iPluginPtr) {
    // Cast succeeded
} else {
    // Cast failed
}
于 2009-10-08T20:12:27.357 に答える
5

この動作はRTTI (Run time type information)と呼ばれます。この手法は避けるのが最善ですが、状況によっては有益な場合もあります。

これを解決するには大きく2つの方法があります。最初の方法は、クラス固有の整数参照コードを返す純粋仮想関数を使用してインターフェイスを作成することです。このコードを使用して、特定のタイプを表すことができます。これらの整数は、特定の列挙に格納できます。

派生クラスでは、メソッドをオーバーライドして、そのクラス固有の型を返すことができます。実行時に、たとえば Plugin->getType() を呼び出すと、特定のタイプが返されます。その後、ポインタに対して static_cast を実行して、派生型の正しいポインタを取得できます。

2 番目の方法は、typeid を使用してオブジェクトのクラスタイプを取得することです。しかし、これはコンパイラに依存します。dynamic_cast を使用してポインターをキャストすることもできます。間違った型にキャストされている場合、dynamic_cast は null ポインターを返します。正しい型にキャストされている場合は有効です。動的キャスト メソッドは、上記の getType メソッドよりもオーバーヘッドが大きくなります。

于 2009-10-08T20:20:26.950 に答える
2

完全な typeof のような動作が必要な場合は、RTTI (実行時の型情報)を使用する必要があります。多くのコンパイラでは、実行時のオーバーヘッドが発生するため、RTTI の使用を明示的に有効にする必要があります。

次に、typeidまたはdynamic_castを使用してオブジェクトの型を見つけることができます。

typeid を使用したくない場合は、継承、ポインター、および/またはオーバーロードを使用する必要があります。ブーストが役立つかもしれませんが、それほど難しくはありません。

例 1:

class Iplugin { ... }

class Plugin1 : public Iplugin { ... }
class Plugin2 : public Iplugin { ... }

void getplugins(Iplugin* p) {
    // ... you don't know the type, but you know
    // what operations it supports via Iplugin
}

void getplugins(Plugin1& p) {
    // expliticly handle Plugin1 objects
}

ご覧のとおり、RTTI と typeid の使用を回避する方法がいくつかあります。

于 2009-10-08T20:04:50.197 に答える
2

この問題を回避する設計が最善の選択です。通常、オブジェクト指向を適切に使用すると役立ちますが、たとえば、各オブジェクトの識別子を格納する基本クラスを使用して、オブジェクトの型を照会するための独自のシステムをいつでも作成できます。

オブジェクトのタイプを見つけるために文字列比較を使用することが最も多いため、dynamic_cast の使用は常に避けてください。これにより、処理が非常に遅くなります。

于 2009-10-08T20:32:39.423 に答える
2

GCC で typeof() を使用できます。他のコンパイラでは、サポートされていないか、クレイジーなテンプレートマングリングを行うか、コンパイラ固有の「バグ機能」を使用する必要があります (Boost のように)。

于 2009-10-09T07:27:43.393 に答える
1

Boost には typeof があります。C++ 0x は typeof とは呼びませんが、同じ種類の機能を提供する 'auto' と 'decltype' の両方を持っています。

そうは言っても、この場合、あなたが本当に探しているものを提供するものはどれもないと確信しています.

于 2009-10-08T20:49:49.153 に答える
1

確かに、オーバーロードを使用するだけですか?

static PluginManager::GetPlugins(Type1 &x) {
  // Do something
}

static PluginManager::GetPlugins(Type2 &x) {
  // Do something else
}

そして、次のように呼び出します。

PluginManager::GetPlugins(IPlugin);
于 2011-03-22T16:06:41.837 に答える
0

「C++でtypeof()を取得する方法」に直接答えることはありませんが、あなたの質問から、C++でプラグインを実行する方法を検討していると推測されます。その場合は、(まだ)Boost.Extensionライブラリに興味があるかもしれませんし、おそらくその反映部分に興味があるかもしれません。

于 2009-10-09T14:11:52.533 に答える