C++;是否有现有方法检查对象是否为派生类型对象? C++是否有一种检查对象是否是派生类型对象的方法?比如说, class A {}; class B : public A {}; A* p;

C++;是否有现有方法检查对象是否为派生类型对象? C++是否有一种检查对象是否是派生类型对象的方法?比如说, class A {}; class B : public A {}; A* p;,c++,dynamic-cast,C++,Dynamic Cast,并检查p是否指向B如果类是多态的(即至少有一个虚拟成员函数),则可以使用dynamic\u cast或typeid 否则,不会。跟踪对象的动态类型是有代价的,而且该语言的设计目的是避免对不需要它的代码感到悲观 并检查p是否指向B 如果类中至少有一个virtual成员函数,则可以使用dynamic\u cast。使析构函数虚拟是很常见的 class A { virtual ~A() {} }; 然后呢, B* bPtr = dynamic_cast<B*>(p); if ( b

并检查
p
是否指向
B

如果类是多态的(即至少有一个虚拟成员函数),则可以使用
dynamic\u cast
typeid

否则,不会。跟踪对象的动态类型是有代价的,而且该语言的设计目的是避免对不需要它的代码感到悲观

并检查
p
是否指向
B

如果类中至少有一个
virtual
成员函数,则可以使用
dynamic\u cast
。使析构函数
虚拟
是很常见的

class A
{
   virtual ~A() {}
};
然后呢,

B* bPtr = dynamic_cast<B*>(p);
if ( bPtr )
{
   // Use the pointer
}
B*bPtr=dynamic_cast(p);
如果(bPtr)
{
//使用指针
}

C++是否有一个检查对象是否是派生类型对象的方法?< /P> 实际上有两种方法可以实现这一点:

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.

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

使用std::is_base_of如下:注意,还必须使用std::remove_引用,因为*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
}
#包括
#包括
A类{};
B类:公共A{};
int main(){
A A;
B B;
A*pa=&A;
B*pb=&B;


std::cout…你是说like?
std::is_base_of
可以让你在编译时测试它。@jaggedSpire:这应该会失败,因为类型不是多态的。@doug:这是
a
相对于
B
的编译时属性,而不是
p
@pixelschemist:它在对象上是可行的。请看我的答案。你期望它是什么o如何处理分配的对象,特别是当它不是多态性的时候?我建议你删除你的第一个方法,它是可疑的方法。@SergeyA修复了这个问题。你可以在编译时使用
std::is_base_of
来确定它,而不需要多态性。请看我的答案。@doug,这就是OP想要的。他有一个基类类型的指针,并且想要确定它是否真的指向派生类。@R Sahu:我的答案演示了如何将其与指向类对象的指针一起使用。您阅读了答案中的代码吗?抱歉,描述不清楚。修复了。@doug,您弄错了。您无法确定编译时
a*
是否真的指向
B
对象。Yes,我读过你的答案。我甚至构建并运行了它。@R Sahu:我同意,如果对象是多态的,你在编译时无法确定它,但OP的示例不是多态的。不!你完全可以确定这个需要多态行为的w/o。修订:你只能测试指向的对象是否有特定的base类,如果它是非多态性的。不,您不能在编译时使用
std::is_base_of
执行OP想要执行的操作。@R Sahu:OP的问题似乎是关于非多态性类的。您可以测试指向实例的指针是否具有特定的基类。我不知道有什么方法可以测试它是否派生自未指定的类。@R Sahu:I'suspect OP对多态对象感兴趣,我在考虑模板代码,有时候你想测试基类在一组可能性中是什么。我已经看到了,但已经有一段时间了。大多数模板都不是多态的。我没有看到虚拟方法,所以假设他说的是非多态基类屁股测试。现在你知道了,你应该删除你的答案。它并不能真正解决OP。@ R萨胡:我倾向于同意。我澄清了答案,但是基于他的问题和标签C++ + C++ 11,我现在很确定非多态基类测试不是OP所考虑的。问题本身只会使SENS。e当使用模板时,如果仅限于非多态性的情况,因为这是唯一一次您对基类不确定。我对模板的了解太久了。
class A { 
public:
    virtual ~A() {} // <<<<<<<<<<<<<<<<<<
};
#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
}