gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 00:51:58 25 4
gpt4 key购买 nike

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

我想先说我正在使用 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 函数正常工作。如果它不是virtual,那么编译本身就会失败(如果Shape 类中没有其他函数是virtual)。如果源类型不是多态的,动态转换将失败。

如果它是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++ - typeid.name() 在遍历 vector 时不会改变。动态转换和 typeid 基类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53531927/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com