c++ - 迭代 vector 时 typeid.name() 不会改变。动态转换和 typeid 基类指针

标签 c++ types polymorphism

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

我想首先说我正在使用 C++ 和 Qt 我有一个形状指针 vector (基类)

编辑: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();

这里我想迭代 vector

    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 总是会在上面的情况下产生正方形,并且当之后立即与圆运行时......动态转换是否对 vector 作为一个整体做了一些事情,我只是错过了一些关于 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();
            }
        }


}

最佳答案

这与作为虚拟函数的doSomething一起工作。如果它不是virtual,那么编译本身就会失败(如果Shape类中没有其他virtual函数)。如果源类型不是多态的,动态转换将会失败。

如果它是虚拟,则无需执行当前操作来确定类型。让多态发挥其魔力。您可以像这样缩短代码:

#include <iostream>
#include <vector>

class Shape { public: virtual void doSomething() {std::cout << "In Shape\n";}};
class Circle: public Shape {public: void doSomething() {std::cout << "In Circle\n";}};
class Square: public Shape {public: void doSomething() {std::cout << "In Square\n";}};

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

    for(auto tmp = vec.begin();tmp != vec.end(); ++tmp)
    {       
        (*tmp)->doSomething();        
    }
}

关于c++ - 迭代 vector 时 typeid.name() 不会改变。动态转换和 typeid 基类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53531927/

相关文章:

c++ - 什么是中性语言、用户默认 LANGID 和系统默认 LANGID?

c++ - C/C++ argv 内存管理

C# 将对象列表中的对象转换为类型返回左手签名必须是变量错误

Java-继承实现

c++ - 如果我向 QTreeWidget 添加一个项目,它总是被插入到第一行

MySQL使用AS表达式时设置数据类型

haskell - 函数类型签名中的右结合性

c++ - 多态继承不覆盖基类方法

编译时的 C++ 类型检查

c++ - 如何查找目标文件 *.o 的 ram rom 使用情况(.bss .text .rodata .data)?