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(运行时类型信息)。最好避免这种技术,但在某些情况下可能是有益的。

有两种方法可以解决这个问题。第一种方法是编写一个带有纯虚函数的接口,该函数返回一个类特定的整数引用代码。然后,此代码可用于表示特定类型。这些整数可以存储在特定的枚举中。

在派生类中,您可以覆盖该方法并返回该类的特定类型。在运行时,你可以调用 Plugin->getType() 例如,它会返回它的特定类型。然后,您可以对指针执行 static_cast 以获取派生类型的正确指针。

第二种方式是要么使用 typeid 获取对象的类类型;但这取决于编译器。您也可以尝试使用 dynamic_cast 投射您的指针;dynamic_cast 在被转换为错误类型时返回一个空指针;并且在以正确类型强制转换时有效。动态转换方法比上面描述的 getType 方法具有更大的开销。

于 2009-10-08T20:20:26.950 回答
2

围绕这个问题进行设计将是最佳选择。良好地使用面向对象通常会有所帮助,但您始终可以创建自己的系统来查询对象的类型,例如,使用存储每个对象的标识符的基类。

始终尽量避免使用 dynamic_cast,因为它最常使用字符串比较来查找对象的类型,这使得它非常慢。

于 2009-10-08T20:32:39.423 回答
2

您可以在 GCC 中使用 typeof() 。对于其他编译器,它要么不受支持,要么您必须进行疯狂的模板修改或使用非常特定于编译器的“错误功能”(就像 Boost 的方式一样)。

于 2009-10-09T07:27:43.393 回答
2

如果您想要完整的类似 typeof 的行为,则必须使用RTTI (run-time type information)。在许多编译器上,您必须明确激活 RTTI 的使用,因为它会产生运行时开销。

然后您可以使用typeiddynamic_cast来查找对象的类型。

如果您不想使用 typeid,则必须使用继承、指针和/或重载。Boost可能会对您有所帮助,但这并不难。

示例 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 回答
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 回答