【问题标题】:Seeing what class an object is查看对象是什么类
【发布时间】:2010-12-13 07:03:27
【问题描述】:

如果我有一个指向 C++ 中基类 A 的指针,我如何能够在我的代码中判断该指针指向派生类 BC

【问题讨论】:

标签: c++ class inheritance pointers base


【解决方案1】:

假设基类A是多态的(即它至少有一个虚函数),你可以使用dynamic_cast。给定一个A* ap;

if (B* bp = dynamic_cast<B*>(ap)) {
    // the object is a B
}
else if (C* cp = dynamic_cast<C*>(ap)) {
    // the object is a C
}

【讨论】:

  • 为了提高可读性并避免来自编译器的'did you mean "=="' cmets,我更喜欢if((blah) != 0)。只是口味问题。
  • @sje397:这行不通,因为在这种情况下blah 是一个声明,而不是一个表达式。因为是声明,= 不是operator=,而且我认为大多数编译器不会在这里发出警告。
  • @James:仍然不明白 - 它必须评估为“假”才能作为if中的条件@是吗?
  • @sje397 和@wrongusername:如果对象不是被转换为的类型或从被转换为的类型派生的类型,则dynamic_cast 将返回0,评估为false .否则它会返回一个指向你已经有一个指针的对象的指针,但是这个指针会知道它指向一个派生类型的对象。
  • 我问了一个问题来帮助澄清:stackoverflow.com/questions/4427228/…
【解决方案2】:

您通常不需要知道:

struct A {
    virtual int generate_foo() = 0;
};

struct B : A {
    int generate_foo() { return 42; }
};

struct C : A {
    i_;
    C(int i) : i_(i) { }
    int generate_foo() { return i_++; }
};

如果你有一个 A*,你 (1) 知道它有一个 generate_foo() 方法,并且 (2) 知道 generate_foo() 将为你真正拥有的任何对象生成一个适当的 foo。一般来说,这应该足够了,您应该能够跟踪您何时拥有A*

从哲学上讲,C++ 的设计者花了数年时间试图避免添加运行时类型信息,因为它太容易被错误地使用。然而,他们最终认为他们在一场失败的战斗中走错了路,并添加了dynamic_casttypeinfo()。 C++0x 会添加更多。

【讨论】:

    【解决方案3】:

    另一种方法,

    if ( typeid(*pBase) == typeid(A))
    {
          cout << "A" << endl;
    }
    else if ( typeid(*pBase) == typeid(B))
    {
          cout << "B" << endl;
    }
    else if ( typeid(*pBase) == typeid(C))
    {
          cout << "C" << endl;
    }
    else
    {
          cout << "something else" <<endl;
    }
    

    但我更喜欢 James 的方法,因为使用它不仅可以确定 类型还可以使用类型转换的实例,然后!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 2013-03-25
      相关资源
      最近更新 更多