Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;多态性:如何测试一个类是否派生自另一个基类?_C++_Polymorphism - Fatal编程技术网

C++ C++;多态性:如何测试一个类是否派生自另一个基类?

C++ C++;多态性:如何测试一个类是否派生自另一个基类?,c++,polymorphism,C++,Polymorphism,抱歉标题的措辞;我不知道如何使它变得更好。但我问题的要点是: #include <iostream> using namespace std; class Base {}; class Base2 {}; class C : public Base, public Base2 {}; class D : public Base {}; void isDerivedFromBase2(Base *p) { if (...) { /* test whether the "re

抱歉标题的措辞;我不知道如何使它变得更好。但我问题的要点是:

#include <iostream>
using namespace std;

class Base {};
class Base2 {};
class C : public Base, public Base2 {};
class D : public Base {};

void isDerivedFromBase2(Base *p) {
    if (...) { /* test whether the "real object" pointed by p is derived from Base2? */
        cout << "true" << endl;
    }
    cout << "false" << endl;
}
int main() {
    Base *pc = new C;
    Base *pd = new D; 
    isDerivedFromBase2(pc); // prints "true"
    isDerivedFromBase2(pd); // prints "false"

    // ... other stuff
}
#包括
使用名称空间std;
类基{};
类Base2{};
C类:公共基,公共基2{};
D类:公共基{};
void是从base2(Base*p)派生的{
如果(…){/*测试p所指的“真实对象”是否来自Base2*/

cout您可以这样执行
dynamic\u cast

 if (dynamic_cast<Base2 *>(p)) {
if(动态投影(p)){


与使用
typeid的方法不同,这个方法不需要包含额外的头,但是它也依赖于RTTI(这意味着这些类需要是多态的)。

这听起来像是一个X-Y问题

对RTTI的需求(或对其派生类的对象进行测试的需求)通常是糟糕设计的标志-您根本不应该需要这样的测试/信息。
如果层次结构设计良好,虚拟函数将承担这些测试的角色


为了找出设计不好的地方,问问自己‘一旦我有了信息,我将如何处理它?’答案总是类似‘我将做一个if/开关/…以不同的方式对待它们’;正确的解决方案是以同样的方式对待它们——调用一个虚拟方法,每个对象都携带正确的vir的知识实际方法知道需要做什么。

@AlanBirtles只要RTTI可用,您就可以。@DanielLangr我已经提到过这一点。@Leedhai:您在运行时请求类型信息,我相信这些词的顺序与RTTI;)不同。@Leedhai好吧,要确定指向您的对象指针的类型,您需要他的信息在运行时的某个地方可用。普通RTTI通过指向存储在每个类实例中的vtable的指针使此信息可用。例如,您可以通过在每个
类实例中存储类类型枚举器值来创建自己的RTTI类机制。RTTI的另一种形式是为rom不同的池。通过这种方式,您可以通过查询这些池来确定对象指针指向的类型。@Leedhai好吧,它实际上和常规RTTI有着完全相同的缺点,它没有添加vtable指针,而是添加了某种类型的类id值。基本上它是“创建您自己的类似RTTI的机制”诸如此类。使用
std::is_base_of
@未知is_base_of不起作用,因为第二个模板参数必须是派生类类型,但现在我的对象由
base*
表示,因此
decltype(*p)
只是
Base
。可以使用
dynamic\u cast
或您自己的
dynamic\u cast
实现,但您必须创建一些反射系统