首页 > 解决方案 > typeid.name() 在遍历向量时不会改变。动态转换和 typeid 基类指针

问题描述

答:总之使用虚函数!因此,实际上不要将其用作好的设计,而是出于学习目的阅读!

我想首先说我正在使用 c++ 和 Qt 我有一个 Shape 指针向量(基类)

编辑: doSomething() 不是基类的成员,而是派生类的成员。这就是为什么我使用 dynamic_cast 将 Shape* 获取到 Derived* 以便我可以访问它的原因。在这一点上,我真的只是出于好奇和其他人学习 c++ 的类型系统

    #include <vector>
    using namespace std;
    vector<Shape *> vec;

我推回一些派生类的形状

    vec.push_back(new Square());
    vec.push_back(new Circle());

好的,然后我得到一个迭代器开始

    vector<Shape *>::iterator tmp = vec.begin();

在这里我想遍历向量

    for(;tmp != vec.end(); ++tmp)
    {
        if(typeid(**tmp).name() == typeid(Square).name())
        {
            Square * sptr = dynamic_cast<Square *>(*tmp);
            sptr->doSomething();
        }
        else if(typeid(**tmp).name() == typeid(Circle).name())
        {
            Circle * cptr = dynamic_cast<Circle *>(*tmp);
            cptr->doSomething();
        }
    }

然而,两者都导致 Square 输出;不是第二个圆圈。我尝试比较 typeid 的内存位置

像这样:

    &typeid(**tmp) == &typeid(Square)

与圆形相同,但 tmp 总是导致上述情况下的正方形,然后当对着圆形运行时...动态转换是否对整个向量做一些事情我只是错过了 typeid() 如何工作的东西?

编辑:这是答案,感谢 user4581301(我也添加了一些东西!):

#include <iostream>
#include <vector>
#include <typeinfo>

struct Shape
{
    virtual ~Shape(){} //Something here must be virtual or pure virtual!
};

struct Circle: Shape
{
    void doSomething(){std::cout << "Circle" << std::endl;}
};
struct Square: Shape
{
    void doSomething(){std::cout << "Square" << std::endl;}
};

int main()
{
    std::vector<Shape *> vec;
    vec.push_back(new Square());
    vec.push_back(new Circle());
    std::vector<Shape *>::iterator tmp = vec.begin();

        for(;tmp != vec.end(); ++tmp)
        {
            if(&typeid(**tmp) == &typeid(Square))
            {
                Square * sptr = dynamic_cast<Square *>(*tmp);
                sptr->doSomething();
            }
            else if(&typeid(**tmp) == &typeid(Circle))
            {
                Circle * cptr = dynamic_cast<Circle *>(*tmp);
                cptr->doSomething();
            }
        }


}

标签: c++typespolymorphism

解决方案


为了使动态转换起作用,基类中的任何函数都必须是虚拟的,这意味着基类必须以多态方式使用。


推荐阅读