C++ 是否有现有方法来检查对象是否为派生类型对象?

Does C++ have existing method to check if an object is a derived-typed object?

C++ 是否有现成的方法来检查对象是否为派生类型对象?例如,

class A
{};

class B : public A
{};

A* p;

并检查 p 是否指向 B

如果 class 是多态的(即至少有一个虚拟成员函数),您可以使用 dynamic_casttypeid.

否则,没有。跟踪对象的动态类型是有代价的,语言旨在避免悲观化不需要它的代码。

And check if p points to B.

如果 class 中至少有一个 virtual 成员函数,您可以使用 dynamic_cast。通常使析构函数 virtual.

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

然后,

B* bPtr = dynamic_cast<B*>(p);
if ( bPtr )
{
   // Use the pointer
}

Does C++ have existing method to check if an object is a derived-typed object?

实际上有两种方法可以实现:

A* p = new B(); 
B* pB = static_cast<B*>(p); // Checks if B is related to A in an inheritance 
     // ^^^^^^^^^^^^^^^^^^^    hierarchy. Fails to compile if not.

A* pA = new B();
B* pB = dynamic_cast<B*>(pA); // Checks if pA actually points to an instance of B
     // ^^^^^^^^^^^^^^^^^^^^     at runtime, and returns nullptr if not
if(pB) {
  // do stuff with B
}

后一个例子要求你有一个 virtual 基础 class:

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

如果所讨论的对象不是多态的class,则可以在编译时确定指向的class对象是否具有特定的基class。这有时会发生在模板代码中,其中可能存在不同的基 classes。

您按如下方式使用 std::is_base_of:请注意,您还必须使用 std::remove_reference,因为 *p 是一个左值并且 decltype() 会生成一个引用。

#include  <type_traits>
#include <iostream>

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

int main() {
    A a;
    B b;
    A* pa=&a;
    B* pb=&b;
    std::cout << std::is_base_of<A, B>::value << "\n";  // true
    std::cout << std::is_base_of<B, A>::value << "\n";  // false
    std::cout << std::is_base_of<A, std::remove_reference<decltype(*pb)>::type>::value << "\n";  // true
    std::cout << std::is_base_of<B, std::remove_reference<decltype(*pa)>::type>::value << "\n";  // false
}