2015-11-08 97 views
0

所以我想要做的是实现消息模式。据我所知,用户将根据我输入的消息类型进行操作,而不是执行操作的消息类型。因此,这是我如何处理它:在运行时确定对象类型的最佳方法

我想要得到的对象的数据类型,所以我可以做一个switch语句,但我不会因此知道从哪里开始。

我已经通过谷歌搜索,并做了一些研究,但没有成功。这是我曾尝试:

  • Decltype:甚至还没有接近我想要的
  • 的typeof:我不是如何使用
  • 动态铸如此清晰:不接近我想要

基本上,我想在结尾处是这样的:

switch (typeof(a)) { 
    class_a : //do something 
    class_b : //do something 
} 

if语句会工作相同为了我。谁能帮我吗?我宁愿使用标准库。

+1

请参阅'boost :: variant' – fghj

+0

@ user1034749有没有办法做到这一点,而不使用局外人的lib? –

+1

这可能是[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。你想达到什么目的? – bolov

回答

2

有一个在标准C没有typeof ++(尽管存在由该名称的GCC扩展名)。您正在寻找typeid操作员。这将返回对包含对象的运行时类型信息(RTTI)的实例的引用。您可以比较的结果到typeid是你感兴趣的各种类别的

作为一个简单的例子(see it run at ideone):

#include <iostream> 
#include <typeinfo> 

class A { 
public: 
    virtual ~A() {} 
}; 

class B: public A {}; 
class C: public A {}; 


int main() { 
    const A& a = C{}; 

    const auto& id = typeid(a); 

    if(id == typeid(B)) { 
     std::cout << "Got a B." << std::endl; 
    } 
    else if(id == typeid(C)) { 
     std::cout << "It's a C!" << std::endl; 
    } 

    return 0; 
} 

(请注意,您不能使用switch,因为对象不是整数)。此示例将打印It's a C!

注意,在一般情况下,使用RTTI不应该是你的第一个反应(须要谨慎,特别是如果你的语言如Java,其中动态类型来了 - 和它相关的速度击中 - 被认为是理所当然) 。相比于其它面向对象的范例,甚至动态调度(virtual函数)

RTTI速度比较慢。如果您试图实现消息模式,请考虑将明确的值作为消息传递,而不是将其他对象固定在模式中,并导致RTTI的开销很大。

+0

我有两个问题:1.如果我坚持这一点,基本上我将不得不存储我想比较的类型的对象,对吧?它不能直接与班级(蓝图)本身进行比较? 2.通过传递明确的价值作为消息,你的意思是什么? –

+0

如果您愿意,您可以直接将引用传递给'std :: type_info'结构;你不必实例化一个对象(例如,看看我在做'typeid(B)')。如果我理解正确,您只是试图在组件之间发送消息,然后根据消息执行不同的操作?通常你可以简单地发送一个'enum'的实例(显式值),这个速度与你在C++中获得的速度一样快。在你使用'typeid'之后,你在做什么? – thirtythreeforty

+0

因此,对于我目前的架构,我有3种不同类型的消息和1个用户。每条消息都有一个基类作为BaseMessage。我使用factoryPattern创建一条消息传递给用户。根据消息的类型,我会让用户采取不同的行动。但我刚想到一种逃避方法,在每个子类中创建一个新变量并在其中放入一个枚举。然后用户可以轻松检查枚举以获取消息类型:D –

0

动态投:不接近我想要

你持有它错了。动态演员当然可以做你想做的。

if (dynamic_cast<c1*>(a)) { ... } 
else if (dynamic_cast<c2*>(a)) { ... } 

*a的静态类型必须是多态的。同样的事情适用于参考。如果你按价值传递它,它不会也不行。然而

这是实现这个的危险和容易出错。如果您希望为M个收件人类型实现N个消息类型,并且所有M×N个操作可能有所不同,请考虑使用访问者模式,尤其是非循环实现。

+0

嗨。我完全知道这种虚拟方法的使用。正如我在文章开头引用的,我试图实现消息模式,它要求用户知道我传入的对象的类型。所以谢谢:) –

+0

删除了基本建议,增加了高级建议。 –

相关问题